2016-01-19 68 views
0

我想通過創建並傳遞字符串作爲參數到aggregate()函數來在R中「即時」調用聚合函數。功能。除了子集參數外,我幾乎可以爲所有參數做到這一點。如何將字符串作爲參數在集合函數中作爲參數「subset」參數

例如:我想運行下面的一段代碼: GG1 < - 骨料(公制〜grouping_var1 + grouping_var2,數據=在data.set,FUN = 「意思是」,子集= exclude.filter == 0)

我可以創建字符串變量,我可以傳遞給聚合函數:只要

current.metric <- "metric" 
    rhs <- c("grouping_var1","grouping_var2") 
    func1 <- "mean" 
    filter <- "exclude.filter == 0" 
    gg1 <- aggregate(as.formula(paste(current.metric, paste(rhs, collapse="+"), sep="~")), data=data.set, FUN= "mean", subset=exclude.filter==0) 

上面一段代碼可以作爲子集= exclude.filter == 0被設置爲參數。我無法弄清楚如何使用像subset = filter這樣的東西。我已經嘗試過表達式(過濾器),替代(過濾器),as.formula(過濾器)作爲參數在子集參數,但我不解析表達式在我認爲正確的環境。

另一種方法是構造整個字符串並將其傳遞給eval()。但是,我想知道它是否可以在聚合函數本身內完成。請有人指出我正確的方向來解決這個問題嗎?

+0

才能添加標籤說明您正在使用的編碼語言的平臺。更明確。 –

+0

我很抱歉,我是這個論壇的新手。我之前添加了「R」標籤,但尚未添加「R-Windows」。我在Windows 8上使用R(在RStudio中,如果有幫助的話) –

+0

爲什麼你想要這樣做?在'parent.frame()'中進行評估的'model.frame()'有一個調用,這就是使用'subset'參數的地方。我認爲這很難破解。 – Thomas

回答

0

改成這樣:

filt <- quote(exclude.filter == 0) 

,或者如果你需要傳遞一個值,然後使用

然後嘗試:

varname = "exclude.filter" 
val = 0 
filt <- substitute(var == value, list(var=as.name(varname),value=val)) 

gg1 <- aggregate(as.formula(paste(current.metric, paste(rhs, collapse="+"), sep="~")), 
        data=data.set, FUN= "mean", subset= eval(filt)) 
+0

謝謝你。但是rawr的解決方案與我所尋找的更相關,因爲它允許我即時構建過濾條件。 –

0

更好的答案應該是「找到一個更好的辦法」但你仍然可以通過這樣的字符串:

data.set <- mtcars 
current.metric <- "mpg" 
rhs <- c("vs","gear") 
func1 <- "mean" 
filt <- "am == 0" 

aggregate(as.formula(paste(current.metric, paste(rhs, collapse="+"), sep="~")), 
      data=data.set, FUN= func1, subset = eval(parse(text = filt))) 
# vs gear  mpg 
# 1 0 3 15.05000 
# 2 1 3 20.33333 
# 3 1 4 21.05000 

aggregate(mpg ~ vs + gear, data = mtcars[mtcars$am == 0, ], FUN = mean) 
# vs gear  mpg 
# 1 0 3 15.05000 
# 2 1 3 20.33333 
# 3 1 4 21.05000 

## or 
aggregate(mpg ~ vs + gear, data = mtcars, FUN = mean, subset = am == 0) 

編輯

沒有這樣一個很好的例子,由於任務是一個一行了,但你可以創建一個包裝函數來設置默認值,使打字變得更容易,消除錯誤,等等

agg <- function(data = mtcars, vars = 'mpg', by_vars = c('vs','gear'), FUN = mean, ...) { 
    aggregate(x = data[, vars], by = data[, by_vars], FUN = FUN, ...) 
} 


agg() 
# vs gear  mpg 
# 1 0 3 15.05000 
# 2 1 3 20.33333 
# 3 0 4 21.00000 
# 4 1 4 25.24000 
# 5 0 5 19.12500 
# 6 1 5 30.40000 

agg(vars = c('mpg','disp')) 
# vs gear  mpg  disp 
# 1 0 3 15.05000 357.6167 
# 2 1 3 20.33333 201.0333 
# 3 0 4 21.00000 160.0000 
# 4 1 4 25.24000 115.6200 
# 5 0 5 19.12500 229.3250 
# 6 1 5 30.40000 95.1000 
agg(FUN = sum) 
# vs gear mpg 
# 1 0 3 180.6 
# 2 1 3 61.0 
# 3 0 4 42.0 
# 4 1 4 252.4 
# 5 0 5 76.5 
# 6 1 5 30.4 

agg(mtcars[mtcars$am == 0, ]) 
# vs gear  mpg 
# 1 0 3 15.05000 
# 2 1 3 20.33333 
# 3 1 4 21.05000 

agg(by_vars = c('cyl','gear')) 
# cyl gear mpg 
# 1 4 3 21.500 
# 2 6 3 19.750 
# 3 8 3 15.050 
# 4 4 4 26.925 
# 5 6 4 19.750 
# 6 4 5 28.200 
# 7 6 5 19.700 
# 8 8 5 15.400 
+0

這太好了,正是我想要的。但是,你能否詳細說明「找到更好的方法」?是否因爲這種解決方案存在缺點(就運行時間或解決方案而言)還是存在其他原因? –

+0

@RaviChandra IMO「公式」和「子集」參數用於交互式使用,不適用於程序使用,就像您似乎在之後那樣,因此您需要跳過一些環節才能使其工作。另外你可能想爲這個任務寫一個簡單的包裝函數。我會添加一些東西 – rawr