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

时间:2015-08-22 04:38:58

标签: r dplyr

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

例如:

| 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中干净地完成这项工作。

我错过了什么?

感谢所有帮助,感激不尽。

2 个答案:

答案 0 :(得分:4)

除了评论中提到的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解决方案和dplyr解决方案summarize_each的缺点是所有列都是相加的。从您想要的输出来看,您不希望PropExp& CropExp总结。您可以通过在.SDcols中指定必须使用data.tableselect中使用dplyr进行汇总的列来实现此目的:

# 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

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

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

答案 1 :(得分:0)

除了已经提供的内容之外,更简洁的方法是使用plyr的ddply功能:

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