如何使用 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_each
dplyr
解决方案的缺点是对所有列求和。从您想要的输出来看,您不希望 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))
我正在尝试确定根据两列选择将数据框中的一组行折叠为一行的最佳方法。
例如:
| 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_each
dplyr
解决方案的缺点是对所有列求和。从您想要的输出来看,您不希望 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))