【问题标题】:Attaching object without using attach() or with()不使用 attach() 或 with() 附加对象
【发布时间】: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


【解决方案1】:

怎么样:

do.with  <-  function(context,fun,args=list()){
    env  <-  as.environment(context)
    parent.env(env)  <-  environment(fun)
    environment(fun)  <- env
    do.call(fun,args)
}

context = list(x=1,y=2)
add = function() x + y
do.with(context,add)


context = list(x=2)
parameters = list(y=5)
mult = function(y) x * y
do.with(context,mult,parameters)

【讨论】:

  • 正是我想要的。谢谢!
猜你喜欢
  • 2012-02-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-04
  • 2018-05-15
  • 2019-02-18
相关资源
最近更新 更多