按组计算

时间:2019-01-30 14:53:12

标签: r

使用下面的代码,我通过分组变量(组)获得了一组变量(var1,var2和var3)的平均值,并在行和组类别中以列显示变量。有其他替代方法吗?

var1 <- c(1,4,3,2,4)
var2 <- c(5,2,3,2,1)
var3 <- c(3,3,2,4,5)
group <- c("A","B","A","A","B")
mydata <- data.frame(var1,var2,var3,group)
m <- aggregate(cbind(var1, var2, var3)~group, mydata, mean)
m
m <- as.matrix(m)
t(m)

3 个答案:

答案 0 :(得分:3)

这是tidyverse

的一个选项
library(tidyverse)
mydata %>%
   group_by(group) %>% 
   summarise_all(mean) %>% 
   gather(key, val, -group) %>% 
   spread(group, val)

或者将base RbycolMeans一起使用

do.call(cbind, by(mydata[1:3], mydata$group, FUN = colMeans))
#.          A   B
#var1 2.000000 4.0
#var2 3.333333 1.5
#var3 3.000000 4.0

或者使用split

使其紧凑
sapply(split(mydata[1:3], mydata$group), colMeans)

答案 1 :(得分:3)

在data.table中测试patterns的新.SDcols的一个好例子。 需要data.table 1.12.0!

很好,因为您可以在此示例中使用正则表达式模式"^var"来轻松选择要对其进行汇总的列...有点像tidyverse中的(大)tidy-selector,但是使用data.table速度优势:)

只需要一行代码!

library( data.table )
setDT(mydata)[, lapply( .SD, mean ), by = .( group ), .SDcols = patterns( "^var" )][]

#    group var1     var2 var3
# 1:     A    2 3.333333    3
# 2:     B    4 1.500000    4

基准化

microbenchmark::microbenchmark(
data.table = setDT(mydata)[, lapply( .SD, mean), by = .( group ), .SDcols = patterns( "^var" )][],
tidyverse = {mydata %>%
  group_by(group) %>% 
  summarise_all(mean) %>% 
  gather(key, val, -group) %>% 
  spread(group, val)
})

# Unit: milliseconds
# expr      min       lq     mean   median       uq       max neval
# data.table 1.884407 1.994217 3.095897 2.619641 2.847096 47.288805   100
# tidyverse 5.003995 5.402869 5.650821 5.633938 5.836086  6.643474   100

答案 2 :(得分:2)

@akrun提供了一种不错的dplyrtidyr方法。这是reshape2的补充

library(dplyr)
library(tidyr)
library(reshape2)
mydata %>% 
  group_by(group) %>% 
  summarise_all(mean) %>% 
  melt() %>% 
  dcast(variable~group)

使用data.table

library(data.table)
setDT(mydata)
DT<-mydata[,lapply(.SD,mean),by=.(group),.SDcols=c("var1","var2","var3")]
melted<-melt.data.table(DT,id.vars = "group")
dcast(melted,variable~group)