在数据框中计算多个列的平均值

12

想知道是否可以仅使用均值函数计算多列的均值。

例如:

mean(iris[,1])

可以实现,但不能保证

mean(iris[,1:4])

尝试过:

mean(iris[,c(1:4)])

收到该错误信息:

警告信息:在 mean.default(iris[, 1:4]) 中 : 参数不是数字或逻辑值:返回 NA

我知道可以使用以下方法之一: lapply(iris[,1:4],mean) 或者 sapply(iris[,1:4],mean)


6
colMeans(iris[,1:4])是什么意思?对data.frame取均值已经不再推荐使用。既然你已经了解了sapply/lapply的解决方案,我不确定为什么你还指望这个会有效。 - MrFlick
дҪҝз”Ё?colMeansжҲ–иҖ…applyж–№жі•еҸҜиғҪжҳҜи§ЈеҶіиҝҷдёӘй—®йўҳзҡ„жңҖдҪіж–№ејҸпјҢдҪҶд№ҹи®ёеңЁиҝҷз§Қжғ…еҶөдёӢжңҖеҘҪзҡ„ж–№жі•жҳҜеңЁstackoverflowдёҠиҝӣиЎҢжҗңзҙўгҖӮ - SabDeM
3个回答

13

尝试使用colMeans函数:

但是该函数要求列中的数据必须为数值型。对于较大的数据集,您可以添加一个检查条件来排除非数值型的数据。

colMeans(iris[sapply(iris, is.numeric)])
Sepal.Length  Sepal.Width Petal.Length  Petal.Width 
    5.843333     3.057333     3.758000     1.199333 

基准测试

对于 dplyrdata.table 来说,似乎有点长。也许有人可以复制结果以验证其准确性。

microbenchmark(
  plafort = colMeans(big.df[sapply(big.df, is.numeric)]),
  Carlos  = colMeans(Filter(is.numeric, big.df)),
  Cdtable = big.dt[, lapply(.SD, mean)],
  Cdplyr  = big.df %>% summarise_each(funs(mean))
  )
#Unit: milliseconds
#    expr       min        lq     mean    median       uq       max
# plafort  9.862934 10.506778 12.07027 10.699616 11.16404  31.23927
#  Carlos  9.215143  9.557987 11.30063  9.843197 10.21821  65.21379
# Cdtable 57.157250 64.866996 78.72452 67.633433 87.52451 264.60453
#  Cdplyr 62.933293 67.853312 81.77382 71.296555 91.44994 182.36578

数据

m <- matrix(1:1e6, 1000)
m2 <- matrix(rep('a', 1000), ncol=1)
big.df <- as.data.frame(cbind(m2, m), stringsAsFactors=F)
big.df[,-1] <- lapply(big.df[,-1], as.numeric)
big.dt <- as.data.table(big.df)

谢谢,我使用lapply太久了,它返回的是列表。 - Pierre L
@user20650 colMeans(Filter(is.numeric,iris)) 请将其翻译为中文。 - Carlos Cinelli
@CarlosCinelli:不错啊,我似乎从来没有使用过这个Negate等等。看看Filter,它只是unlist(lapply(..)),但更加简洁。 - user20650
@user20650 看起来也稍微快了一点。 - Pierre L

8

使用sapply + Filter

sapply(Filter(is.numeric, iris), mean)
Sepal.Length  Sepal.Width Petal.Length  Petal.Width 
    5.843333     3.057333     3.758000     1.199333 

使用 dplyr

library(dplyr)
iris %>% summarise_each(funs(mean))
   Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1:     5.843333    3.057333        3.758    1.199333      NA

PS:在dplyr中,您现在可以使用summarize_if函数进行汇总。

iris %>% summarise_if(is.numeric, mean)
#>   Sepal.Length Sepal.Width Petal.Length Petal.Width
#> 1     5.843333    3.057333        3.758    1.199333

使用 data.table

library(data.table)
iris <- data.table(iris)
iris[,lapply(.SD, mean)]
   Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1:     5.843333    3.057333        3.758    1.199333      NA

1
也许是 iris %>% summarise_each(funs(mean), -Species) - Steven Beaupré
使用dplyr时,“funs(mean)”已被弃用,应改用“list(mean=mean)”代替。 - Angel Cloudwalker

0

假设列以正确的 is.numeric 格式存在,则您上面的解决方案有效。请参见以下示例:

a <- c(1,2,3)
mean(a)

b <- c(2,4,6)
mean(b)

d <- c(3,6,9)

mydata <- cbind(b,a,d)


mean(mydata[,1:3])

2
这不完全正确。上面的示例是一个 data.frame,并且没有一种方法可以在 data.frame 上使用 mean。你的示例(有点)可行,因为你可以取一个 matrixclass(mydata))的均值:但它给出的是整体的平均值而不是按列的。 - user20650

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