2012-04-16 72 views
19

我希望能夠發送一個列名稱給我打電話給ddply。一個例子ddply電話:從列名發送到ddply從函數

ddply(myData, .(MyGrouping), summarise, count=sum(myColumnName)) 

如果我已經ddply包裹另一個函數內是有可能把這個包起來,這樣我可以作爲myColumnName調用函數的任意值傳遞?

+0

你有一個可重現的例子(有數據,例如使用虹膜)嗎? – 2012-04-16 19:25:04

+0

@static_rtti你是專門尋找'plyr'的答案嗎?這個問題很老,現在有更多先進的軟件包。 – 2015-04-15 11:57:09

+0

那麼,我使用plyr(並不知道更高級的軟件包),但是如果您可以用不同的軟件包提供相同問題的答案,我也會發現它很有趣。 – 2015-04-15 11:59:58

回答

11

必須有更好的方法。我無法弄清楚如何使它與總結一起工作。

my.fun <- function(df, count.column) { 
    ddply(df, .(x), function(d) sum(d[[count.column]])) 
} 

dat <- data.frame(x=letters[1:2], y=1:10) 

> my.fun(dat, 'y') 
    x V1 
1 a 25 
2 b 30 
> 
+0

您可以直接將count.column傳遞給'ddply'中的函數,如下所示:'ddply(df,。(x),function(d)sum(d [[count.column]]))'避免'eval'。 – 2012-04-16 17:38:55

+0

@TylerRinker是的,那個eval是我試圖讓它與總結一起工作時的一個延期。編輯。 – Justin 2012-04-16 17:42:21

+0

我也試過這個(但是因爲不再真正使用plyr)我也無法弄清楚如何使它與總結一起工作。 – 2012-04-16 17:44:32

7

這似乎工作,儘管它可能會更清潔(更安全),以避免在這種情況下summarise,寫自己的匿名函數賈斯汀表示。

yr <- "year" 

summarise(baseball, 
duration = max(eval(parse(text = yr))) - min(eval(parse(text = yr)))) 
4

正如@David Arenburg所說的那樣,這個問題相當古老。今天,data.tabledplyr軟件包可以以更快的速度爲您提供相同的結果。

這裏是data.table版本的答案。

library(data.table) 
my.fun <- function(myData, MyGrouping, myColumnName) { 
    setDT(myData)[, lapply(.SD, sum), by=MyGrouping, .SDcols=myColumnName] 
} 
0

我想我找到了一種方法是工作與總結。我不知道如果我明白爲什麼,因爲我不是專家,與環境中的R處理,但這裏的解決方案:

> library(plyr) 
> 
> 
> 
> ########################### 
> # Creating test DataFrame # 
> ########################### 
> 
> x <- 1:15 
> 
> set.seed(1) 
> y <- letters[1:3][sample(1:3, 15, replace = T)] 
> 
> df <- data.frame(x, y) 
> 
> ### check df 
> df 
    x y 
1 1 a 
2 2 b 
3 3 b 
4 4 c 
5 5 a 
6 6 c 
7 7 c 
8 8 b 
9 9 b 
10 10 a 
11 11 a 
12 12 a 
13 13 c 
14 14 b 
15 15 c 
> 
> 
> ##################### 
> # auxiliar function # 
> ##################### 
> evalString <- function(s) { 
+ eval(parse(text = s), parent.frame()) 
+ } 
> 
> 
> ### columnName input 
> columnName <- 'x' 
> 
> ### call with columnName as input 
> xMeans <- ddply(df, 
+     'y', 
+     summarise, 
+     mean = mean(evalString(columnName))) 
> 
> 
> ### regular call to ddply 
> xMeans2 <- ddply(df, 
+     'y', 
+     summarise, 
+     mean = mean(x)) 
> 
> 
> ### Compare Results 
> xMeans 
    y mean 
1 a 7.8 
2 b 7.2 
3 c 9.0 
> xMeans2 
    y mean 
1 a 7.8 
2 b 7.2 
3 c 9.0 
> 

編輯:您可以使用get功能從基礎包,作爲建議這裏:ddply: how do I pass column names as parameters?

> xMeans3 <- ddply(df, 
+     'y', 
+     summarise, 
+     mean = mean(get(columnName))) 
> 
> xMeans3 
    y mean 
1 a 7.8 
2 b 7.2 
3 c 9.0