2013-05-20 44 views
17

我有這樣一個數據幀:應用功能有條件

experiment iter results 
    A  1  30.0 
    A  2  23.0 
    A  3  33.3 
    B  1  313.0 
    B  2  323.0 
    B  3  350.0 
.... 

有沒有辦法通過應用功能與條件相符的結果。在上面的例子中,該條件是特定實驗的所有迭代。

A sum of results (30 + 23, + 33.3) 
B sum of results (313 + 323 + 350) 

我在想「應用」功能,但找不到一種方法來使它工作。

回答

43

有很多替代品可以做到這一點。請注意,如果您有興趣從sum不同的另一個功能,那麼就改變說法FUN=any.function,e.g,如果你想meanvarlength等,則只需將這些功能集成到FUN說法,e.g,FUN=meanFUN=var等。讓我們來探索一些替代方案:

aggregate函數在基地。

> aggregate(results ~ experiment, FUN=sum, data=DF) 
    experiment results 
1   A 86.3 
2   B 986.0 

也許tapply

> with(DF, tapply(results, experiment, FUN=sum)) 
    A  B 
86.3 986.0 

從plyr包

> # library(plyr) 
> ddply(DF[, -2], .(experiment), numcolwise(sum)) 
    experiment results 
1   A 86.3 
2   B 986.0 

> ## Alternative syntax 
> ddply(DF, .(experiment), summarize, sumResults = sum(results)) 
    experiment sumResults 
1   A  86.3 
2   B  986.0 

另外,dplyr

另外ddply

> require(dplyr) 
> DF %>% group_by(experiment) %>% summarise(sumResults = sum(results)) 
Source: local data frame [2 x 2] 

    experiment sumResults 
1   A  86.3 
2   B  986.0 

使用sapplysplit,相當於tapply

> with(DF, sapply(split(results, experiment), sum)) 
    A  B 
86.3 986.0 

如果你對時間的關注,data.table是你的朋友:

> # library(data.table) 
> DT <- data.table(DF) 
> DT[, sum(results), by=experiment] 
    experiment V1 
1:   A 86.3 
2:   B 986.0 

不那麼受歡迎,但doBy包是很好(相當於aggregate,即使是在語法!)

> # library(doBy) 
> summaryBy(results~experiment, FUN=sum, data=DF) 
    experiment results.sum 
1   A  86.3 
2   B  986.0 

而且by有助於在這種情況下

> (Aggregate.sums <- with(DF, by(results, experiment, sum))) 
experiment: A 
[1] 86.3 
------------------------------------------------------------------------- 
experiment: B 
[1] 986 

如果你想要得到的結果是一個矩陣然後使用cbindrbind

> cbind(results=Aggregate.sums) 
    results 
A 86.3 
B 986.0 

sqldf從sqldf包也可能是一個不錯的選擇

> library(sqldf) 
> sqldf("select experiment, sum(results) `sum.results` 
     from DF group by experiment") 
    experiment sum.results 
1   A  86.3 
2   B  986.0 

xtabs也適用(僅當FUN=sum

> xtabs(results ~ experiment, data=DF) 
experiment 
    A  B 
86.3 986.0 
+8

+1它不會比這更全面的... –