我得到了以下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'的方法,但是由于某种原因,我得到的数字略高(我猜有些行被重复了)。关于如何改进此代码的任何建议?)。感谢您的帮助!
答案 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
keep
包中的函数purrr
来仅保留针对该条件的TRUE
列。group_by
和summarise
。我认为str_detect
和keep
函数是一种不错的方法,因为如果正确标记了数据框,它们将提供灵活性。