我得到了以下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'的方法,但由于某种原因我获得了稍高的数字(我猜有些行是重复的)。关于如何改进此代码的任何建议?)。谢谢你的帮助!
这是获取子集的更动态的方法,假设您希望分割每个列,即
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
这个怎么样?
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
keep
包中的函数purrr
,只保留TRUE
列的条件。group_by
和summarise
如你所愿。我认为str_detect
和keep
函数是一种很好的方法,因为如果您的数据帧被正确标记,它们可以提供灵活性。