有条件地应用function

我有这样的数据框:

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) 

我正在考虑“应用”function,但无法find工作的方法。

有很多替代品可以做到这一点。 请注意,如果您对另一个不同于sum函数感兴趣,那么只需更改参数FUN=any.function ,例如,如果需要meanvar length等,那么只需将这些函数插入FUN参数,例如FUN=meanFUN=var等等。 让我们探索一些替代scheme:

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)) AB 86.3 986.0 

也从plyr包ddply

 > # 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

 > 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)) AB 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 

不太stream行,但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 

如果你想要的结果是一个matrix,然后使用cbindrbind

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

来自sqldf包的sqldf也可能是一个不错的select

 > 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 AB 86.3 986.0