【问题标题】:Apply function conditionally有条件地应用函数
【发布时间】:2013-05-20 20:07:56
【问题描述】:

我有一个这样的数据框:

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)

我正在考虑“应用”功能,但找不到让它工作的方法。

【问题讨论】:

    标签: r aggregate


    【解决方案1】:

    有很多替代方法可以做到这一点。请注意,如果您对不同于sum 的另一个函数感兴趣,则只需更改参数FUN=any.function,例如,如果您想要meanvar length 等,那么只需将这些函数插入@987654326 @ 参数,例如,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 包的 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))
        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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-08-17
      • 2018-09-19
      • 2011-01-14
      • 2011-07-18
      • 2010-12-02
      • 1970-01-01
      • 2016-02-15
      相关资源
      最近更新 更多