dplyr能否在不列出每个变量的情况下对多个变量进行汇总?

80

dplyr非常快,但我想知道是否有什么我错过的东西:是否可以对多个变量进行汇总。例如:

library(dplyr)
library(reshape2)

df <- data.frame(
  sex = factor(rep(c("boy", "girl"), each = 2L)),
  age = c(52L, 58L, 40L, 62L),
  bmi = c(25L, 23L, 30L, 26L),
  chol = c(187L, 220L, 190L, 204L)
)
df

   sex age bmi chol
1  boy  52  25  187
2  boy  58  23  220
3 girl  40  30  190
4 girl  62  26  204

dg=group_by(df,sex)

通过这个小数据框,编写起来很容易

summarise(dg,mean(age),mean(bmi),mean(chol))

我知道要得到我想要的,我可以融合、获取手段,然后进行强制类型转换

dm=melt(df, id.var='sex')
dmg=group_by(dm, sex, variable); 
x=summarise(dmg, means=mean(value))
dcast(x, sex~variable)

但是如果我有超过20个变量和非常多的行,该怎么办?是否有类似于data.table中的 .SD 的东西,可以让我在分组数据框中计算所有变量的平均值?或者,是否可能在分组数据框上使用lapply?

感谢任何帮助


7
我认为 data.table 的解决方案在这里将是最快和更有效的。但您也可以拥有一个好的 "reshape2 only" 解决方案:dcast(melt(df, id = "sex"), sex ~ variable, fun.aggregate = mean) - dickoa
2个回答

120

正如几位用户所提到的,mutate_each()summarise_each()已被废弃,推荐使用新的across()函数。

dplyr版本1.0.5的最新答案:

df %>%
  group_by(sex) %>%
  summarise(across(everything(), mean))

原始回答:

dplyr现在有了summarise_each函数:

df %>% 
  group_by(sex) %>% 
  summarise_each(funs(mean))

1
summarise_each替代方案的版本更新可以在这里找到:https://dev59.com/mWEi5IYBdhLWcg3wG45o#39284283 - leerssej
3
жҳҜзҡ„пјҢз”ұдәҺsummarise_eachе·Іиў«ејғз”ЁпјҢдҪ еҸҜиғҪжғіеңЁOPзҡ„еә”з”ЁдёӯдҪҝз”Ёsummarise_allжҲ–зұ»дјјзҡ„дёңиҘҝгҖӮ - DirtStats
1
summarise_each has been deprecated. df %>% group_by(sex) %>% summarise(across(everything(), mean)) - Jason Mathews

44

data.table 的用法是 lapply(.SD, mean),意思是:

data.table idiom is lapply(.SD, mean), which means:
DT <- data.table(df)
DT[, lapply(.SD, mean), by = sex]
#     sex age bmi  chol
# 1:  boy  55  24 203.5
# 2: girl  51  28 197.0

我不确定是否有与此相同的dplyr习惯用语,但您可以尝试以下操作:

dg <- group_by(df, sex)
# the names of the columns you want to summarize
cols <- names(dg)[-1]
# the dots component of your call to summarise
dots <- sapply(cols ,function(x) substitute(mean(x), list(x=as.name(x))))
do.call(summarise, c(list(.data=dg), dots))
# Source: local data frame [2 x 4]

#    sex age bmi  chol
# 1  boy  55  24 203.5
# 2 girl  51  28 197.0

请注意,有一个github问题#178,旨在高效实现dplyr中的colwise惯用语plyr


3
我认为目前使用dplyr这是最好的做法。唯一要改变的是将sapply()替换为lapply(),因为没有进行简化操作。 - hadley
1
请注意,dplyr现在有summarize_each()和mutate_each()函数:http://finzi.psych.upenn.edu/library/dplyr/html/summarise_each.html - Bar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接