我有两个数据帧。对于df1的某些行,在df2中有匹配的行。现在,应该对df1的一些列进行操作,使它们包含自己的值和df2中的等价值之和。
在下面的示例中,应该对列'count1‘和'count2’求和,而不是对列'type‘求和。
df1 <- data.frame(id = c("one_a", "two_a", "three_a", "four_a"), type = c(8,7,6,5), count1 = c(1,2,1,NA), count2 = c(NA,0,1,0), id_df2 = c("one", "two", "three", "four"))
df2 <- data.frame(id = c("one", "two", "four"), type = c(8,7,5), count1 = c(0,1,1), count2 = c(0,0,1))
result <- data.frame(id = c("one_a", "two_a", "three_a", "four_a"), type = c(8,7,6,5), count1 = c(1,3,1,1), count2 = c(0,0,1,1))
> df1
       id type count1 count2 id_df2
1   one_a    8      1     NA     one
2   two_a    7      2      0     two
3 three_a    6      1      1   three
4  four_a    5     NA      0    four
> df2
    id type count1 count2
1  one    8      0      0
2  two    7      1      0
3 four    5      1      1
> result
       id type count1 count2
1   one_a    8      1      0
2   two_a    7      3      0
3 three_a    6      1      1
4  four_a    5      1      1也有类似的问题,我试图通过拆分数据帧并随后将其合并来找到解决方案。我只是想知道是否有更优雅的方式来做这件事。我的原始数据集大约有300列,所以我正在寻找一个可伸缩的解决方案。
预先感谢chuckmorris
发布于 2019-01-30 23:46:35
你可以这样做:
library(dplyr)
df1 %>% select(-id_df2) %>%
  bind_rows(df2) %>%
  mutate(id = gsub("_.*", "", id)) %>%
  replace(., is.na(.), 0) %>%
  group_by(id, type) %>%
  summarise_at(vars(contains("count")), funs(sum))其中,输出为:
# A tibble: 4 x 4
# Groups:   id [?]
  id     type count1 count2
  <chr> <dbl>  <dbl>  <dbl>
1 four      5      1      1
2 one       8      1      0
3 three     6      1      1
4 two       7      3      0但也包括:
df1 %>% select(-id_df2) %>%
  bind_rows(df2) %>%
  mutate(id = ifelse(grepl("_", id), id, paste0(id, "_a"))) %>%
  replace(., is.na(.), 0) %>%
  group_by(id, type) %>%
  summarise_at(vars(contains("count")), funs(sum))如果您对保留_a部件感兴趣。
另一种方法是使用join,转换为long,然后向后传播,如:
library(tidyverse)
df1 %>% 
  left_join(df2, by = c("id_df2" = "id")) %>%
  gather(var, val, -id) %>%
  mutate(var = gsub("\\..*", "", var)) %>%
  distinct(id, var, val) %>%
  filter(!var == "id_df2") %>%
  group_by(id, var) %>%
  summarise(val = sum(as.numeric(val), na.rm = T)) %>%
  spread(var, val) 给予:
# A tibble: 4 x 4
# Groups:   id [4]
  id      count1 count2  type
  <fct>    <dbl>  <dbl> <dbl>
1 four_a       1      1     5
2 one_a        1      0     8
3 three_a      1      1     6
4 two_a        3      0     7如果_a结束有特殊目的,这可能是有意义的,例如,还有带有_b、_c等的组(在这种情况下,上面的方法将失败)。
发布于 2019-01-31 04:52:29
稍微不那么优雅,但仍然有效:
result_2 <- df2 %>% 
  mutate(id = paste0(id, "_a")) %>%
  bind_rows(df1) %>% 
  select(-id_df2) %>% 
  replace(., is.na(.), 0) %>%
  group_by(id) %>% 
  summarise(count1 = sum(count1), count2 = sum(count2), type = max(type)) %>% 
  mutate(id_df2 = as.factor(id)) %>% 
  select(c(id_df2, type, count1, count2), -id)https://stackoverflow.com/questions/54444226
复制相似问题