【发布时间】:2016-06-10 22:55:43
【问题描述】:
这可能看起来是一个奇怪的请求,但我希望从本质上临时附加一个对象,以便可以从所述对象中提取单个元素,但实际上并未使用 attach() 或 with()。例如,我很清楚这两种方法可以按名称索引 data.frame 元素”
obj <- data.frame(N=2, sd=1)
myfun <- function(obj){
N2 <- obj$N^2
rnorm(N2, obj$sd)
}
myfun(obj)
myfun2 <- function(obj){
with(obj, {
N2 <- N^2
rnorm(N2, sd)
})
}
myfun2(obj)
但是,我想要的是更一般的东西,形式可以是
# wanted
myfun3 <- function(){
N2 <- N^2
rnorm(N2, sd)
}
with(obj, myfun3()) #this is the idea but clearly doesn't work
因此不需要显式索引obj 的元素,并且可以避免将整个语句包装在with() 函数中。显然myfun3() 没有找到obj 的内部结构,但我愿意。以下工作正常,从功能的角度来看正是我想要的,但远非犹太:
attach(obj)
myfun3()
detach(obj)
附加通常被认为是不好的,并且出于我的目的,这段代码必须在 R 包中工作,因此甚至不允许 attach() (同样,它嵌套在另一个可以并行运行的函数中...... ..所以出口到全球环境可能不是一个好的解决方案)。
最终,我希望这一切在安全的并行计算环境中如下工作
library(parallel)
cl <- makeCluster()
parfun <- function(index, obj, myfun){
out <- with(obj, myfun())
out
}
parSapply(cl=cl, 1:100, parfun, obj=obj, myfun=myfun3)
任何想法将不胜感激。
【问题讨论】:
-
唯一让我困惑的是标题说你不想使用
with(),但你想要的例子使用with()? -
你可以看看
within。它是with的扩展,允许多次调用。 -
为什么?
fortunes::fortune(379)。 “解决”attach来完成同样的事情在 CRAN 的 R 包中不会比使用attach更洁净。生产代码(如包中的函数)应该依赖于传递给它们的参数,而不是希望在全局或父环境中存在且不会被覆盖的对象。 -
这就是为什么 Hadley 包中的函数带有标准评估对应函数的原因 - 例如,
aes_和aes_string。您可能想查看lazyeval包 - 但归根结底,他的建议是函数的标准评估版本是主力,而 NSE 版本是用于非编程方便的轻型包装器。 The main lazyeval vignette 很好读,NSE section of Advanced R 也是。 -
@Gregor
attach被广泛认为是 R 编程中最糟糕的做法...
标签: r