【问题标题】:R: Passing parameters from a wrapper function to internal functionsR:将参数从包装函数传递到内部函数
【发布时间】:2012-07-30 21:24:14
【问题描述】:

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

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

但 df.basic 中确实存在 dprime,它被 with() 引用。谁能解释这个问题?谢谢!

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

【问题讨论】:

  • 这是哪种编程语言?
  • R, r-project.org(抱歉,我以为我标记了它。感谢您的编辑)。
  • 给我们看看df.basicdput(head(df.basic)) 的样子

标签: r function parameters


【解决方案1】:

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

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

会起作用的。

【讨论】:

  • 啊,这是一个好点。谢谢!抱歉,我猜这是一个愚蠢的问题。
  • @ChrisCox -- 这不是一个愚蠢的问题!正如@Michael 所暗示的那样,“问题”实际上与with() 的工作方式有关。 (这就是为什么以编程方式使用with() 通常是不好的做法)。试试下面看看(感谢惰性评估)实际上dprime 不需要在computeMeans() 的环境中可用:computeMeans &lt;- function(a,b) a; computeMeans(9, dprime)
【解决方案2】:

或者

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

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

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

【讨论】:

    【解决方案3】:

    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)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-10-04
      • 1970-01-01
      • 2014-01-03
      • 2018-09-26
      • 2021-09-21
      • 1970-01-01
      • 2015-10-12
      • 2015-02-17
      相关资源
      最近更新 更多