在同一数据框中汇总多个组的更好方法
Better way to summarize multiple groups in same dataframe
我不确定用这个词作为标题的更好方式,这可能会妨碍我搜索答案。
我有一个如下所示的数据框:
example_df <- data.frame(
ID = c('A', 'A', 'A', 'B', 'B', 'C', 'C', 'C'),
location = c('park 1', 'park 1', 'park 2', 'park 3', 'park 1', 'park 4', 'park 1', 'park 5'),
sample_2000 = c(1, 5, 0, 2, 3, 1, 0, 8),
sample_2001 = c(2, 1, 1, 3, 5, 6, 4, 2),
sample_2003 = c(1, 2, 5, 8, 11, 1, 0, 7)
)
ID location sample_2000 sample_2001 sample_2003
1 A park 1 1 2 1
2 A park 1 5 1 2
3 A park 2 0 1 5
4 B park 3 2 3 8
5 B park 1 3 5 11
6 C park 4 1 6 1
7 C park 1 0 4 0
8 C park 5 8 2 7
我想按位置对每年的所有值求和,并在同一个数据框中得到结果。我目前正在使用 group_by() 并分别总结每一年,然后将所有内容重新组合在一起:
library(dplyr)
summarize1 <- group_by(example_df, location) %>% dplyr::summarize(sample_2000 = sum(sample_2000))
summarize2 <- group_by(example_df, location) %>% dplyr::summarize(sample_2001 = sum(sample_2001))
summarize3 <- group_by(example_df, location) %>% dplyr::summarize(sample_2003 = sum(sample_2003))
all_summarized <- Reduce(function(x, y) merge(x, y, all=TRUE), list(summarize1, summarize2, summarize3))
所需的输出(我从上面收到的)如下所示:
location sample_2000 sample_2001 sample_2003
1 park 1 9 12 14
2 park 2 0 1 5
3 park 3 2 3 8
4 park 4 1 6 1
5 park 5 8 2 7
肯定有更好的方法。我尝试 for-loop returns 以下内容:
'总和错误(paste0("sample_",i)):
参数'
的无效 'type'(字符)
year_list <- c(2000, 2001, 2003)
for (i in year_list) {
test <- group_by(example_df, location) %>% dplyr::summarize(paste0("sample_", i)) = sum(paste0("sample_", i))
}
谢谢!
如果我们想使用与 Reduce/merge
类似的方法,那么我们可以利用 purrr
中的 map/reduce
library(dplyr)
library(purrr)
map(names(example_df)[3:5], ~
example_df %>%
select(location, .x) %>%
group_by(location) %>%
summarise_at(vars(starts_with('sample')), sum)) %>%
reduce(full_join)
或者使用summarise/across
(在dplyr
的新版本中),我们可以获得相同的输出(虽然不确定该示例是针对一般情况还是与[=18相关的内容) =] 仅)
example_df %>%
group_by(location) %>%
summarise(across(starts_with('sample'), sum))
或使用 dplyr
稳定版本的 summarise_at
(将来可能会弃用)
example_df %>%
group_by(location) %>%
summarise_at(vars(starts_with('sample')), sum)
我不确定用这个词作为标题的更好方式,这可能会妨碍我搜索答案。
我有一个如下所示的数据框:
example_df <- data.frame(
ID = c('A', 'A', 'A', 'B', 'B', 'C', 'C', 'C'),
location = c('park 1', 'park 1', 'park 2', 'park 3', 'park 1', 'park 4', 'park 1', 'park 5'),
sample_2000 = c(1, 5, 0, 2, 3, 1, 0, 8),
sample_2001 = c(2, 1, 1, 3, 5, 6, 4, 2),
sample_2003 = c(1, 2, 5, 8, 11, 1, 0, 7)
)
ID location sample_2000 sample_2001 sample_2003
1 A park 1 1 2 1
2 A park 1 5 1 2
3 A park 2 0 1 5
4 B park 3 2 3 8
5 B park 1 3 5 11
6 C park 4 1 6 1
7 C park 1 0 4 0
8 C park 5 8 2 7
我想按位置对每年的所有值求和,并在同一个数据框中得到结果。我目前正在使用 group_by() 并分别总结每一年,然后将所有内容重新组合在一起:
library(dplyr)
summarize1 <- group_by(example_df, location) %>% dplyr::summarize(sample_2000 = sum(sample_2000))
summarize2 <- group_by(example_df, location) %>% dplyr::summarize(sample_2001 = sum(sample_2001))
summarize3 <- group_by(example_df, location) %>% dplyr::summarize(sample_2003 = sum(sample_2003))
all_summarized <- Reduce(function(x, y) merge(x, y, all=TRUE), list(summarize1, summarize2, summarize3))
所需的输出(我从上面收到的)如下所示:
location sample_2000 sample_2001 sample_2003
1 park 1 9 12 14
2 park 2 0 1 5
3 park 3 2 3 8
4 park 4 1 6 1
5 park 5 8 2 7
肯定有更好的方法。我尝试 for-loop returns 以下内容:
'总和错误(paste0("sample_",i)): 参数'
的无效 'type'(字符)
year_list <- c(2000, 2001, 2003)
for (i in year_list) {
test <- group_by(example_df, location) %>% dplyr::summarize(paste0("sample_", i)) = sum(paste0("sample_", i))
}
谢谢!
如果我们想使用与 Reduce/merge
类似的方法,那么我们可以利用 purrr
map/reduce
library(dplyr)
library(purrr)
map(names(example_df)[3:5], ~
example_df %>%
select(location, .x) %>%
group_by(location) %>%
summarise_at(vars(starts_with('sample')), sum)) %>%
reduce(full_join)
或者使用summarise/across
(在dplyr
的新版本中),我们可以获得相同的输出(虽然不确定该示例是针对一般情况还是与[=18相关的内容) =] 仅)
example_df %>%
group_by(location) %>%
summarise(across(starts_with('sample'), sum))
或使用 dplyr
稳定版本的 summarise_at
(将来可能会弃用)
example_df %>%
group_by(location) %>%
summarise_at(vars(starts_with('sample')), sum)