假设我有以下数据框(注意“分数”的长度):
id = 1:10^8
school = LETTERS[1:10]
class = paste0(school, rep(1:10, each=10))
score = rnorm(10^8)
df = data.frame(id, school, class, score,
stringsAsFactors = FALSE)
我想计算 100 个类别中每个类别的平均值。然而,我也想要 保持结果中学校的变量。使用 dplyr:
df %>% group_by(class) %>%
summarise(mean = mean(score),
school = unique(school))
这可以工作,但是很慢(在我的机器上 8 秒,而且我的数据实际上要大得多)。我认为一个选择可能是不使用 unique() 而是使用 join() 家族的成员。但我需要首先定义另一个 df,如下所示:
df_join = data.frame(class, school,
stringsAsFactors = FALSE)
然后:
df %>% group_by(class) %>%
summarise(mean = mean(score)) %>%
left_join(df_join)
这有效并且速度较慢,因为现在需要 6 秒。然而,在这里创建 df_join 很容易,因为我发明了数据帧,但在现实生活中,获取 df_join 可能更具挑战性。所以我想只使用原始数据帧(df)。
有什么想法可以使用 dplyr 让这变得更容易(也许更快)吗? (我查了一下,但没有找到解决方案:Aggregate by factor levels, keeping other variables in the resulting data frame)
最佳答案
由于每个类(class)只有一所唯一的学校,因此您可以简单地将学校变量包含在分组变量中:
df %>% group_by(school, class) %>% summarize(mean_score = mean(score))
# # A tibble: 100 x 3
# # Groups: school [?]
# school class mean_score
# <chr> <chr> <dbl>
# 1 A A1 0.000506
# 2 A A10 -0.000275
# 3 A A2 0.00136
# 4 A A3 0.000405
# 5 A A4 -0.00156
# 6 A A5 -0.00214
# 7 A A6 -0.00108
# 8 A A7 -0.000534
# 9 A A8 0.000804
# 10 A A9 0.00106
# # ... with 90 more rows
这是一个 data.table 等效项:
library(data.table)
setDT(df, key = c("school", "class"))
df[, .(mean_score = mean(score)), by=.(school, class)]
关于r - 使用 dplyr 聚合数据框,同时保留其他变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50229975/