假设我有以下数据框(注意'得分'的长度):
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)
答案 0 :(得分:3)
由于每个班级只有一个独特的学校,您可以简单地将学校变量包含在分组变量中:
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)]