如何解决汇总所有列,并使用相同的ID
我有12个data.frame,它们具有相同的变量,但行号不同。这些data.frame具有列ID,并且这些ID中的90%在所有data.frame中都是相同的。
ID <- c(1:10)
wage <- c(1500:1509)
bonus <- c(1000:1009)
df1 <- data.frame(ID,wage,bonus)
ID <- c(1:11)
wage <- c(1800:1810)
bonus <- c(1200:1210)
df2 <- data.frame(ID,bonus)
为简化此过程,将data.frames存储在一个列表中,以便您可以像df [[1]],df [[2]]这样访问。
我想创建一个新的数据框,将其称为new_df,它具有相同的变量,但通过ID(以及仅存在于所有data.frames中的ID)对所有列值进行求和。由于每个df都有每月的工资和奖金,因此我的目标是获得年度工资。 非常感谢有人能帮忙。
解决方法
这项工作:
> ID <- c(1:10)
> wage <- c(1500:1509)
> bonus <- c(1000:1009)
>
> df1 <- data.frame(ID,wage,bonus)
>
> ID <- c(1:11)
> wage <- c(1800:1810)
> bonus <- c(1200:1210)
>
> df2 <- data.frame(ID,bonus)
>
> ID <- c(1:20)
> wage <- c(2001:2020)
> bonus <- c(1301:1320)
>
> df3 <- data.frame(ID,bonus)
>
> mylist <- list(df1,df2,df3)
>
> my_df <- do.call(rbind,mylist)
>
> my_df %>% group_by(ID) %>% filter(n() == length(mylist)) %>% summarise(tot_wage = sum(wage),tot_bonus = sum(bonus))
`summarise()` ungrouping output (override with `.groups` argument)
# A tibble: 10 x 3
ID tot_wage tot_bonus
<int> <int> <int>
1 1 5301 3501
2 2 5304 3504
3 3 5307 3507
4 4 5310 3510
5 5 5313 3513
6 6 5316 3516
7 7 5319 3519
8 8 5322 3522
9 9 5325 3525
10 10 5328 3528
>
如果您想选择任意数量的列:
> my_func <- function(df,summary_vars){
+ df %>%
+ summarise(across({{summary_vars}},sum))
+ }
> my_df %>% group_by(ID) %>% filter(n() == length(mylist)) %>% my_func(wage)
`summarise()` ungrouping output (override with `.groups` argument)
# A tibble: 10 x 2
ID wage
<int> <int>
1 1 5301
2 2 5304
3 3 5307
4 4 5310
5 5 5313
6 6 5316
7 7 5319
8 8 5322
9 9 5325
10 10 5328
> my_df %>% group_by(ID) %>% filter(n() == length(mylist)) %>% my_func(bonus)
`summarise()` ungrouping output (override with `.groups` argument)
# A tibble: 10 x 2
ID bonus
<int> <int>
1 1 3501
2 2 3504
3 3 3507
4 4 3510
5 5 3513
6 6 3516
7 7 3519
8 8 3522
9 9 3525
10 10 3528
> my_df %>% group_by(ID) %>% filter(n() == length(mylist)) %>% my_func(c(wage,bonus))
`summarise()` ungrouping output (override with `.groups` argument)
# A tibble: 10 x 3
ID wage bonus
<int> <int> <int>
1 1 5301 3501
2 2 5304 3504
3 3 5307 3507
4 4 5310 3510
5 5 5313 3513
6 6 5316 3516
7 7 5319 3519
8 8 5322 3522
9 9 5325 3525
10 10 5328 3528
>
,
如果您有列表dfs
,则可以使用此dplyr
解决方案
library(dplyr)
dfs <- list(df1,df2)
bind_rows(dfs) %>%
group_by(ID) %>%
summarise(wage = sum(wage),bonus = sum(bonus))
,
要抛出另一种选择,如果您有一个包含所有数据框的列表,则可以使用purrr::map_dfr
将它们绑定在一起。在这种情况下,要映射的函数只是返回数据帧,因此它与bind_rows
没什么不同。但是,如果您想在绑定每个数据框之前对其进行某些操作(例如过滤器),那么map_dfr
是一个不错的选择。
此外,如果您想按ID对所有列值求和,则可以使用summarize_all
。
library(tidyverse)
list(df1,df2) %>%
map_dfr(.f = ~.) %>%
group_by(ID) %>%
summarize_all(sum)
编辑:我错过了@Karthik S获得的过滤步骤。 filter(n() == length(df_lst))
是一个不错的解决方案。
df_lst <- list(df1,df2)
df_lst %>%
map_dfr(.f = ~.) %>%
group_by(ID) %>%
filter(n() == length(df_lst)) %>%
summarize_all(sum)
,
另一种选择是合并base R
函数以附加两个数据帧,然后简单地汇总结果。
library(dplyr)
do.call('rbind',list(df1,df2)) %>%
group_by(ID) %>%
filter(n() == length(list(df1,df2))) %>% #as per Karthik S
summarise_all(.,sum)
# ID wage bonus
# <int> <int> <int>
# 1 1 3300 2200
# 2 2 3302 2202
# 3 3 3304 2204
# 4 4 3306 2206
# 5 5 3308 2208
# 6 6 3310 2210
# 7 7 3312 2212
# 8 8 3314 2214
# 9 9 3316 2216
# 10 10 3318 2218
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。