R:将参数从包装函数传递到内部函数

时间:2012-07-30 21:24:14

标签: r function parameters

我并不感到惊讶,这个功能不起作用,但我不太明白为什么。

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/

3 个答案:

答案 0 :(得分:3)

虽然dprime中存在df.basic,但当您在computeMeans调用它时,它不知道您指的是什么,除非您明确引用它。

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

会奏效。

答案 1 :(得分: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中。

     

在访问该参数之前,没有与之关联的值   诺言。访问参数时,存储的表达式为   在存储的环境中进行评估,并返回结果。该   承诺也保存了结果。

source

因此,无论首次调用promise的环境如何,都会在创建它的环境(即调用函数的环境)中评估promise。观察:

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通过全局环境中的promise分配y值,但y尚未在全局环境中定义。 x在已定义y的环境中调用,但调用x仍会导致指示y不存在的错误。这表明x是在定义了promise的环境中进行评估的,而不是在当前环境中进行评估。

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

答案 2 :(得分:2)

dprime参数作为字符串传递将允许您回避@ Michael的回答中讨论的涉及的范围和评估规则的任何考虑:

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)