2012-07-30 153 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)