【问题标题】:Aggregate a data frame while keeping other variables, with dplyr聚合数据框,同时保留其他变量,使用 dplyr
【发布时间】:2018-05-08 09:09:30
【问题描述】:

假设我有以下数据框(注意'score'的长度):

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

【问题讨论】:

  • 使用df %>% group_by(school, class) %>% summarize(...)

标签: r statistics dplyr data-manipulation summary


【解决方案1】:

由于每个班级只有一所独特的学校,您可以简单地将学校变量包含在分组变量中:

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)]

【讨论】:

  • 谢谢。但是按附加变量分组会减慢该过程。虽然你的方法比使用 unique() 快,但是比我使用的 join() 慢。
  • @Rtist,如果你关心速度,你应该切换到data.table
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-07-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-07-21
  • 2018-07-23
  • 1970-01-01
相关资源
最近更新 更多