【问题标题】:R ddply summarise sum only selected/specific/logical rowsR ddply 仅汇总选定/特定/逻辑行
【发布时间】:2015-11-13 08:05:40
【问题描述】:

我有一个客户贷款数据库,我想对每个 LoanRefID 进行 ddply 汇总:

    LoanRefId               Tran_Type TransactionAmount
103        11               LoanIssue         1000.0000
104        11           InitiationFee          171.0000
105        11                Interest           59.6729
106        11       AdministrationFee           64.9332
107        11 RaisedClientInstallment         1295.5757
108        11       ClientInstallment         1295.4700
109        11                  PaidUp            0.0000
110        11              Adjustment            0.1361
111        11                  PaidUp            0.0000
112        12               LoanIssue         3000.0000
113        12           InitiationFee          399.0000
114        12                Interest           94.9858
115        12       AdministrationFee           38.6975
116        12 RaisedClientInstallment         3532.6350
117        12       ClientInstallment         3532.6100
118        12                  PaidUp            0.0000
119        12              Adjustment            0.0733
120        12                  PaidUp            0.0000

但是,我只想对每个loanID 的某些行求和。具体来说,我只想总结 Tran_Type == "ClientInstallment" 的位置。

我能想到的唯一方法(似乎行不通)是:

> ddply(test, c("LoanRefId"), summarise, cash_in = sum(test[test$Tran_Type == "ClientInstallment","TransactionAmount"]))

  LoanRefId cash_in
1        11 4828.08
2        12 4828.08

这不是每个 LoanRefId 的总和,它只是将 Tran_Type == "CLientInstallment" 错误的所有金额相加。

有没有更好的方法来做这个逻辑和?

【问题讨论】:

    标签: r dataframe plyr


    【解决方案1】:

    有人可能会添加plyr 答案,但现在base Rdplyrdata.table 使用更广泛。 plyr 已更新和升级。值得花时间学习更新的实现,因为它们更高效且功能丰富。

    基础R

    aggregate(TransactionAmount ~ LoanRefId, df[df$Tran_Type == "ClientInstallment",], sum)
    #  LoanRefId TransactionAmount
    #1        11           1295.47
    #2        12           3532.61
    

    dplyr

    library(dplyr)
    df %>% 
      group_by(LoanRefId) %>% 
      filter(Tran_Type == "ClientInstallment") %>%
      summarise(TransactionAmount = sum(TransactionAmount))
    #Source: local data frame [2 x 2]
    #
    #  LoanRefId TransactionAmount
    #      (int)             (dbl)
    #1        11           1295.47
    #2        12           3532.61
    

    data.table

    setDT(df)[Tran_Type == "ClientInstallment", sum(TransactionAmount), by=LoanRefId]
    #   LoanRefId      V1
    #1:        11 1295.47
    #2:        12 3532.61
    

    注意data.table 语法是多么干净:)。学习的好工具。

    【讨论】:

    • Pierre Lafortune,感谢您的详细解答。我对 R 很陌生,我很羡慕能够有 3 种方法来实现相同(复杂)的事情。如果我可能再次滥用您的帮助意愿:我实际上需要做"ClientInstallment" minus "LoanIssue"。这可以使用 data.tables 和/或 dplyr 吗?
    • 每个id都会有一个吗?
    • 好点,我怀疑不是!在这种情况下,我可能需要进行干预并将两者都设为零,以免扭曲我的分析或通过删除这些行预先清理数据?
    • 是的,这取决于您要寻找的最终结果。如果您确定需要减法,您可以通过这两个值进行过滤,然后根据需要进行减法。
    • Pierre Lafortune,不知道怎么可能,但你的 dplyr 建议对我不起作用:> test %>% + group_by(LoanRefId) %>% + filter(Tran_Type == "ClientInstallment") %>% + summarise(TransactionAmount = sum(TransactionAmount)) TransactionAmount 1 4828.08
    【解决方案2】:

    另一个base R 选项是tapply

     with(subset(df1, Tran_Type=='ClientInstallment'),
          tapply(TransactionAmount, LoanRefId, FUN=sum))
     #    11      12 
     #1295.47 3532.61 
    

    或者如果我们需要plyr(回到过去)

    library(plyr)
    ddply(df1, .(LoanRefId), summarise, 
          TransactionAmount = sum(TransactionAmount[Tran_Type=='ClientInstallment']))
    #  LoanRefId TransactionAmount
    #1        11           1295.47
    #2        12           3532.61
    

    【讨论】:

      【解决方案3】:

      这里还有一种可能性,只是为了完整性:

      with(df1[df1$Tran_Type=="ClientInstallment",], by(LoanRefId, TransactionAmount, sum))
      #TransactionAmount: 1295.47
      #[1] 11
      #------------------------------------------------------------ 
      #TransactionAmount: 3532.61
      #[1] 12
      

      【讨论】:

        【解决方案4】:

        老实说,我觉得data.table 是一个救生员。

        test[Tran_Type == "ClientInstallment", 
             sum(TransactionAmount), by=LoanRefId]
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-01-04
          相关资源
          最近更新 更多