如何根据另外两列的键对一列进行求和

时间:2014-12-05 08:37:43

标签: r sum dataframe

我有一个包含三列的data.frame:

To     Amount   Type
Smith  $1       A
John   $5       B
Jeff   $8       A
Smith  $4       C
...    ...      ...

我需要将其转换为数据框,表明每个人收到的每种类型的金额。

Name  TotalAmtOfTypeA  TotalAmtOfTypeB  TotalAmtOfTypeC ...
Smith $1               $0               $4
John  $0               $5               $0
Jeff  $8               $0               $0
...

原始data.frame长度超过300万行,因此解决方案越有效或并行化越好。解决方案是否涉及aggregate?或者我应该调查plyr?任何指导都将非常感谢!

2 个答案:

答案 0 :(得分:2)

以下是两个选项:

library(tidyr)
spread(df, Type, Amount)
#     To ordered.A ordered.B ordered.C
#1  Jeff        $8      <NA>      <NA>
#2  John      <NA>        $5      <NA>
#3 Smith        $1      <NA>        $4

library(reshape2)
dcast(df, To ~ Type, value.var = "Amount")
#     To    A    B    C
#1  Jeff   $8 <NA> <NA>
#2  John <NA>   $5 <NA>
#3 Smith   $1 <NA>   $4

或者,如果您将列类从因子更改为字符,则可以执行以下操作:

df$Amount <- as.character(df$Amount)
dcast(df, To ~ Type, value.var = "Amount", fill = "$0")
#     To  A  B  C
#1  Jeff $8 $0 $0
#2  John $0 $5 $0
#3 Smith $1 $0 $4

同样

spread(df, Type, Amount, fill = "$0")
#     To  A  B  C
#1  Jeff $8 $0 $0
#2  John $0 $5 $0
#3 Smith $1 $0 $4

注意:如果您将“金额”列保留为因子并尝试使用fill = "$0",则会收到如下错误消息:

  

警告消息:在[<-.factor*tmp*,is.na(已订购),值= 0)中:   无效因子水平,NA生成


如果您想在Amount列中删除那些“$”,以便您可以实际使用这些数字进行进一步处理,那么您可以在dplyr / tidyr链中执行此操作:

library(dplyr)
library(tidyr)
df %>%
  mutate(Amount = as.numeric(gsub("\\$", "", Amount))) %>%
  spread(Type, Amount, fill = 0)

#     To A B C
#1  Jeff 8 0 0
#2  John 0 5 0
#3 Smith 1 0 4

答案 1 :(得分:2)

这是一个data.table解决方案应该可以很快地运行:

数据

library(data.table)
n <- 1e6
dat <- data.table(Name = LETTERS[sample(26, n, TRUE)],
                  Amount = rpois(n, 100),
                  Type = letters[sample(26, n, TRUE)])

<强>代码

setkey(dat, Name, Type)
dat.agg <- dat[, .(Sum = sum(Amount)), by =.(Name, Type)]
dat.agg[, as.list(setattr(Sum, 'names', Type)), by = .(Name)]

<强>解释

第一个[.data.table汇总data.table以获得所有Name/Type组合的总和。第二个[.data.table以您希望的方式格式化data.tablesetattr用于获得良好的输出(根据Type的级别对列进行调整。

相关问题