如何使用group_by并汇总来自同一data.frame的多个子集?

时间:2019-04-22 08:21:47

标签: r dplyr

我得到了以下data.frame:

     country1 value1 country2 value2 country3 value3
2375    Other     43   Jordan     30       NA     NA
2366    Other     89   Turkey     29       NA     NA
4904   Turkey     50     Iraq     28       NA     NA
4786   Jordan     20   Turkey     25       NA     NA
5816   Jordan      7   Turkey     10       NA     NA
2365  Lebanon     18    Other      9       NA     NA

其中value1,value2和value3彼此独立。

我基本上想要获得一个汇总每个国家及其汇总值的表格:

  country total_value
1    Iraq         294
2  Jordan         993
3 Lebanon        1632
4   Other         167
5  Turkey         942

我尝试了一种“粗略”的方法,即分别对原始data.frame进行三倍的子集设置,绑定结果子集,然后使用dplyr进行分组和汇总:

subset1 <- my_data %>% select(country = country1, value= value1)

subset2 <- my_data %>% select(country = country2, value = value2)

subset3 <- my_data %>% select(country = country3, value = value3)

subset_all <- bind_rows(subset1, subset2, subset3)

my_result <- subset_all %>% group_by(country) %>% summarise(total_value = sum(value, na.rm=TRUE)) 

我想以更“优雅”的方式获得相同的结果。我尝试过使用dplyr中的'gather'或data.table中的'melt'的方法,但是由于某种原因,我得到的数字略高(我猜有些行被重复了)。关于如何改进此代码的任何建议?)。感谢您的帮助!

2 个答案:

答案 0 :(得分:0)

这是获取子集的一种更动态的方法,假设您想分割每两列,即

df <- unname(df)

do.call(rbind, split.default(df, rep(seq(ncol(df)/2), each = 2))) %>% 
   group_by(country) %>% 
   summarise(res = sum(value)) %>% 
   filter(!is.na(country))

给出,

# A tibble: 5 x 2
  country   res
  <fct>   <int>
1 Jordan     57
2 Lebanon    18
3 Other     141
4 Turkey    114
5 Iraq       28

答案 1 :(得分:0)

怎么样?

result <- data.frame(
  country = as.vector(t(keep(df, str_detect(names(df),  "country")))),
  value = as.numeric(as.vector(t(keep(df, str_detect(names(df),  "value")))))
) %>%
  na.omit() %>%
  group_by(country) %>%
  summarise(res = sum(value, na.rm = TRUE))

result

# A tibble: 5 x 2
  country   res
  <fct>   <dbl>
1 Iraq       28
2 Jordan     57
3 Lebanon    18
4 Other     141
5 Turkey    114
  1. 检测包含“国家”或“值”的名称。
  2. 使用keep包中的函数purrr来仅保留针对该条件的TRUE列。
  3. 创建矢量并创建新的数据框
  4. 摆脱na值
  5. group_bysummarise

我认为str_detectkeep函数是一种不错的方法,因为如果正确标记了数据框,它们将提供灵活性。