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)}
myfunnew.datmutate
不是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)}