如何使用 dplyr 根据列 id 合并行数据

How to use dplyr to merge row data based on a column id

我正在尝试确定根据两列选择将数据框中的一组行折叠为一行的最佳方法。

例如:

| State |Fatalities|Injuries|Dmg   |Dmg|year|eventType| PropExp | CropExp |   
| ------|----------|--------|------|---|----|---------|---------|---------|   
| WA    | 1        | 100    |25.00 |0  |1971|HAIL     |1000000  |1        | 0 |   
| WA    | 6        | 200    |25.00 |0  |1972|TORNADO  |1000000  |1        | 1 |   
| WA    | 2        | 300    |25.00 |0  |1973|SNOW     |1000000  |1        | 0 |   
| WA    | 6        | 900    |65.00 |0  |1973|TORNADO  |1000000  |1        | 1 |   
| WA    | 4        | 300    |25.00 |0  |1973|TORNADO  |1000000  |1        | 0 |   
| WA    | 0        | 900    |65.00 |0  |1972|TORNADO  |1000000  |1        | 1 |

目的是按事件类型合并和添加每年的行...因此我们将 1973 年的 TORNADO 行折叠成一行 - 添加了选定的行数据并创建新的合并数据行...

| State |Fatalities|Injuries|Dmg   |Dmg|year|eventType| PropExp | CropExp |   
| ------|----------|--------|------|---|----|---------|---------|---------|   
| WA    | 1        | 100    |25.00 |0  |1971|HAIL     |1000000  |1        | 0 |   
| WA    | 6        | 200    |25.00 |0  |1972|TORNADO  |1000000  |1        | 1 |   
| WA    | 2        | 300    |25.00 |0  |1973|SNOW     |1000000  |1        | 0 |   
| WA    | 10       | 1200   |90.00 |0  |1973|TORNADO  |1000000  |1        | 1 |   
| WA    | 0        | 900    |65.00 |0  |1972|TORNADO  |1000000  |1        | 1 |

注意:我使用的是来自 Coursera Reproducible Research 课程的示例数据集——我之前已经完成了该课程。这个问题与课程等无关 - 我正在尝试折叠不同的数据集,我很想知道如何在 R 中干净地完成此操作。

我错过了什么?

感谢所有的帮助。

除了评论中提到的dplyr解决方案@Khashaa,你也可以在基础R中这样做:

aggregate(cbind(Fatalities, Injuries, Dmg, Dmg.1, PropExp, CropExp) ~ State + year + eventType, data = df, sum)

这给出:

  State year eventType Fatalities Injuries Dmg Dmg.1 PropExp CropExp
1    WA 1971      HAIL          1      100  25     0 1000000       1
2    WA 1973      SNOW          2      300  25     0 1000000       1
3    WA 1972   TORNADO          6     1100  90     0 2000000       2
4    WA 1973   TORNADO         10     1200  90     0 2000000       2

或者您也可以使用 data.table:

library(data.table)
setDT(df)[, lapply(.SD, sum), by=.(State, year, eventType)]

结果相同。

data.table解决方案和summarize_eachdplyr解决方案的缺点是对所有列求和。从您想要的输出来看,您不希望 PropExp & CropExp 求和。您可以通过指示必须在 data.table 中使用 .SDcols 或在 dplyr 中使用 select 进行汇总的列来实现:

# data.table
setDT(df)[, lapply(.SD, sum),
          by=.(State, year, eventType),
          .SDcols=c("Fatalities","Injuries","Dmg")]

# dplyr
df %>% group_by(State, year, eventType) %>% 
  summarise_each(funs(sum), -PropExp, -CropExp, -Dmg.1)

两者都导致:

   State year eventType Fatalities Injuries Dmg
1:    WA 1971      HAIL          1      100  25
2:    WA 1972   TORNADO          6     1100  90
3:    WA 1973      SNOW          2      300  25
4:    WA 1973   TORNADO         10     1200  90

当然,您仍然可以在 base R 中执行此操作:

aggregate(cbind(Fatalities, Injuries, Dmg) ~ State + year + eventType, data = df, sum)

除了提供的内容之外,更简洁的方法是使用 plyr 的 ddply 函数:

library(plyr)
ddply(df, .(year, eventType), numcolwise(sum))