2012-07-30 155 views
3

我并不感到惊讶,这个函数不起作用,但我不明白为什么。R:从包装函数传递参数到内部函数

computeMeans <- function(data,dv,fun) { 
    x <- with(data,aggregate(dv, 
     list(
      method=method, 
      hypo=hypothesis, 
      pre.group=pre.group, 
      pre.smooth=pre.smooth 
     ), 
     fun)) 
    return(x) 
} 

computeMeans(df.basic,dprime,mean) 

df.basic与因素methodhypothesis等,和多个因变量的一个数据帧(我指定一个与dv参数,dprime)。

我有多个因变量和几个数据帧都是相同的形式,所以我想写这个小函数来保持事情“简单”。我得到的错误是:

Error in aggregate(dv, list(method = method, hypo = hypothesis, 
pre.group = pre.group, : 
    object 'dprime' not found 

但dprime并在df.basic,这与with()引用的存在。任何人都可以解释问题吗?谢谢!

编辑:这是R编程语言。 http://www.r-project.org/

+0

的编程语言是这样吗? – Yogu 2012-07-30 21:27:32

+0

R,http://www.r-project.org/(对不起,我以为我标记了它,感谢编辑)。 – 2012-07-30 21:28:12

+0

给我们一个'df.basic'与'dput(head(df.basic))'' – nograpes 2012-07-30 21:41:11

回答

3

虽然dprime存在于df.basic,当你在computeMeans叫它它不知道你指的是,除非你明确地引用它。

computeMeans(df.basic,df.basic$dprime,mean) 

将工作。

+0

'看起来是什么样子啊,这是一个很好的观点。谢谢!对不起,原来我猜是一个愚蠢的问题。 – 2012-07-30 21:46:16

+0

@ChrisCox - 不是一个愚蠢的问题! '问题'实际上是用'()'的方式,正如@Michael所暗指的那样。 (这就是为什么通常以编程方式使用'with()'的习惯)。尝试以下方法来看看(感谢懒惰的评估),实际上在'computeMeans()'的环境中不需要'dprime':'computeMeans < - function(a,b)a; computeMeans(9,dprime)'。 – 2012-07-30 22:22:15

3

或者

computeMeans <- function(data,dv,fun) { 
    dv <- eval(substitute(dv), envir=data) 
    x <- with(data,aggregate(dv, 
     list(
      method=method, 
      hypo=hypothesis, 
      pre.group=pre.group, 
      pre.smooth=pre.smooth 
     ), 
     fun)) 
    return(x) 
} 

你可能会想,既然DV是在with(data, (.))调用,它就会的data的环境中进行评估。它不是。

当一个函数被调用时,参数被匹配,然后每个 的形式参数被绑定到一个promise。为该正式参数给出的表达式 以及指向环境的指针 函数被存储在promise中。

在访问该参数之前,没有与 承诺相关的值。当访问参数时,存储的表达式将在存储环境中求值 ,并返回结果。诺言也保存了 的结果。因此

source

甲承诺在它被创建的环境(即,其中该函数被调用的环境),而不管环境的,其中承诺首先被调用内进行评价。观察:

delayedAssign("x", y) 
local({ 
    y <- 10 
    x 
}) 
Error in eval(expr, envir, enclos) : object 'y' not found 

w <- 10 
delayedAssign("z", w) 
local({ 
    w <- 11 
    z 
}) 
[1] 10 

请注意,delayedAssign创建了一个承诺。在第一个例子中,x通过全球环境中的承诺被赋予y的值,但y在全球环境中尚未定义。 x在已定义y的环境中调用,但调用x仍然会导致错误,指示y不存在。这表明x在已定义承诺的环境中进行评估,而不是在当前环境中进行评估。

在第二个示例中,z通过全局环境中的承诺分配w的值,并且w在全局环境中定义。然后z在一个环境中被调用,其中w被赋予了不同的值,但z仍然在已经创建承诺的环境中返回w的值。

2

dprime参数传递的字符串将允许你回避的@迈克尔的回答讨论所涉及的范围界定和评价规则的考虑:

computeMeans <- function(data, dv, fun) { 
    x <- aggregate(data[[dv]], 
     list(
      method = data[["method"]], 
      hypo = data[["hypothesis"]], 
      pre.group = data[["pre.group"]], 
      pre.smooth = data[["pre.smooth"]] 
     ), 
     fun) 
    return(x) 
} 
computeMeans(df.basic, "dprime", mean)