data.frames列表中元素的平均值

时间:2011-10-04 17:10:13

标签: r list dataframe plyr

假设我有一个data.frames列表(行和列相等)

dat1 <- as.data.frame(matrix(rnorm(25), ncol=5))
dat2 <- as.data.frame(matrix(rnorm(25), ncol=5))
dat3 <- as.data.frame(matrix(rnorm(25), ncol=5))

all.dat <- list(dat1=dat1, dat2=dat2, dat3=dat3)

如何返回单个data.frame,它是整个列表中data.frames中每个元素的平均值(或总和等)(例如,列表1,2中第一行和第一列的平均值, 3等等)?我在lapply中尝试了ldplyplyr,但这些会返回列表中每个data.frame的统计信息。

编辑:出于某种原因,这被重新作为家庭作业。这不重要,但这不是一个功课问题。我只是不知道为什么我不能让这个工作。感谢您的任何见解!

Edit2:进一步澄清: 我可以使用循环获得结果,但我希望有一种方法(一种更简单,更快捷的方式,因为我使用的数据具有12行×100列的data.frames,并且有1000多个这样的列表数据框)。

z <- matrix(0, nrow(all.dat$dat1), ncol(all.dat$dat1))

for(l in 1:nrow(all.dat$dat1)){
   for(m in 1:ncol(all.dat$dat1)){
      z[l, m] <- mean(unlist(lapply(all.dat, `[`, i =l, j = m)))
   }
}

结果是:

> z
        [,1]        [,2]        [,3]        [,4]       [,5]
[1,] -0.64185488  0.06220447 -0.02153806  0.83567173  0.3978507
[2,] -0.27953054 -0.19567085  0.45718399 -0.02823715  0.4932950
[3,]  0.40506666  0.95157856  1.00017954  0.57434125 -0.5969884
[4,]  0.71972821 -0.29190645  0.16257478 -0.08897047  0.9703909
[5,] -0.05570302  0.62045662  0.93427522 -0.55295824  0.7064439

我想知道是否有更少的笨重和更快的方法来做到这一点。谢谢!

6 个答案:

答案 0 :(得分:16)

这是一张带plyr的单行班轮。您可以将mean替换为您想要的任何其他功能。

ans1 = aaply(laply(all.dat, as.matrix), c(2, 3), mean)

答案 1 :(得分:11)

您可以更轻松地更改数据结构,将三个二维矩阵组合成一个三维数组(使用abind库)。然后使用apply更直接地解决方案并指定要平均的维度。

编辑:

当我回答问题时,它被标记为homework,所以我只是给了一个方法。原来的海报删除了那个标签,所以我会用他/她的话来说明它不是。

library("abind")

all.matrix <- abind(all.dat, along=3)
apply(all.matrix, c(1,2), mean)

答案 2 :(得分:10)

我给出了一个使用完全不同的数据结构来实现结果的答案。这个答案使用直接给出的数据结构(数据帧列表)。我认为它不那么优雅,但无论如何都想提供它。

Reduce(`+`, all.dat) / length(all.dat)

逻辑是逐个元素地添加数据帧(+将对数据帧进行处理),然后除以数据帧的数量。使用Reduce是必要的,因为+一次只能获取两个参数(并且添加是关联的)。

答案 3 :(得分:6)

另一种仅使用base函数来更改对象结构的方法:

listVec <- lapply(all.dat, c, recursive=TRUE)
m <- do.call(cbind, listVec)

现在,您可以使用mean计算rowMeans,或使用median计算apply

means <- rowMeans(m)
medians <- apply(m, 1, median)

答案 4 :(得分:2)

我会采取略微不同的方法:

library(plyr)
tmp <- ldply(all.dat) # convert to df
tmp$counter <- 1:5 # 1:12 for your actual situation
ddply(tmp, .(counter), function(x) colMeans(x[2:ncol(x)]))

答案 5 :(得分:1)

你能不能只使用嵌套的lapply()电话?

这似乎可以在我的机器上显示正确的结果

mean.dat <- lapply(all.dat, function (x) lapply(x, mean, na.rm=TRUE))