R 再次:在函数中设置环境

R 再次:在函数中设置环境,r,function,plyr,environment,R,Function,Plyr,Environment,关于范围界定、环境和功能已经有很多讨论。参见例如,或。但是,我不确定我是否找到了解决以下问题的好方法: df <- data.frame(id=rep(LETTERS[1:2],each=2), x=1:4) d <- -1 myfun <- function(df, d){ require(plyr) new.dat <- ddply(df, .(id), transform, x=x*d) retur

关于范围界定、环境和功能已经有很多讨论。参见例如,或。但是,我不确定我是否找到了解决以下问题的好方法:

 df <- data.frame(id=rep(LETTERS[1:2],each=2), x=1:4)
 d <- -1
 myfun <- function(df, d){
          require(plyr)
          new.dat <- ddply(df, .(id), transform, x=x*d) 
          return(new.dat)}
 myfun(df, 1)
我的理解是,
with(here,d)
从环境
here
中检索对象
d
。因此,结果应该是
1
。但返回了一个错误,即

  Error in eval(substitute(expr), data, enclos = parent.frame()) : 
   invalid 'envir' argument of type 'closure' 
我不确定我是否理解为什么这不起作用,如果有人能对此有所了解,或者如果你能提供替代解决方案,我将非常高兴。请注意,用(…)将整个
ddply
-语句包装成
,似乎也没有帮助

有效的解决方案是将当前环境附加到函数中:

 myfun3 <- function(df, d){
   here <- environment()
   attach(here)
   new.dat <- ddply(df, .(id), transform, x=x*d) 
   detach(here)
   return(new.dat)
 }

myfun3要唤醒惰性计算并确保使用的是本地
d
参数,请使用
force
。添加此行:

d <- force(d)
次要的无关代码改进:
由于当
require
返回
FALSE
时,您没有对案例进行任何处理,因此您应该将其与
库进行交换
mutate
是替代
转换的一种改进的替代品
您不需要显式返回

myfun <- function(df, d){
      library(plyr)
      ddply(df, .(id), here(mutate), x=x*d)}

myfun
new.dat
mutate
不是
transform
的替代品;比较变换(d,x=x*d,y=x)
和变异(d,x=x*d,y=x)
谢谢!这很有启发性。我仍然不明白为什么带有(这里,d)
-的
解决方案不起作用。提供一个数字而不是
d
显然有效。为什么用(这里,d)
不是一回事?我的理解是,从
ddply
的角度来看,两者应该是等价的。@coffeinjunky在
ddply
中,这里的环境
是不可访问的;错误消息令人困惑,因为“here”也是plyr函数的名称。这一点很好!将其更改为
here2
将导致出现
未找到here2对象的消息。因此,
ddply
计算全局环境中的所有内容,也就是说,
使用(here2,d)
在全局环境中进行计算,但是在全局环境中,本地环境
here2
不可见,尽管有明确的地址?这就是问题的原因吗?是的,这就像给火星或塔图因上的人写明信片一样;你想怎么说就怎么说,邮局是够不着的。
myfun <- function(df, d){
      require(plyr)
      new.dat <- ddply(df, .(id), here(transform), x=x*d) 
      return(new.dat)}
myfun <- function(df, d){
      library(plyr)
      ddply(df, .(id), here(mutate), x=x*d)}