(行と列が等しい)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.frames内の各要素の平均(または合計など)である単一のdata.frameを返すにはどうすればよいですか(たとえば、リスト1、2、3などの最初の行と最初の列の平均)オン)? lapply
でldply
とplyr
を試しましたが、これらはリスト内の各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
これを行うためのより不格好でより速い方法があるかどうか疑問に思いました。ありがとう!
これがplyr
のワンライナーです。 mean
を他の任意の関数に置き換えることができます。
ans1 = aaply(laply(all.dat, as.matrix), c(2, 3), mean)
(abind
ライブラリを使用して)3つの2次元行列を1つの3次元配列に結合することで、データ構造を簡単に変更できます。次に、apply
を使用し、平均化するディメンションを指定することで、ソリューションはより直接的になります。
編集:
質問に答えたとき、それはhomework
とタグ付けされていたので、私はただアプローチをしました。元のポスターはそのタグを削除したので、そうではないという彼/彼女の言葉で彼/彼女を連れて行きます。
library("abind")
all.matrix <- abind(all.dat, along=3)
apply(all.matrix, c(1,2), mean)
結果を達成するために完全に異なるデータ構造を使用する1つの答えを与えました。この回答では、直接指定されたデータ構造(データフレームのリスト)を使用します。あまりエレガントではないと思いますが、とにかく提供したかったのです。
Reduce(`+`, all.dat) / length(all.dat)
ロジックは、データフレームを要素ごとに追加することです(これは+
はデータフレームで行います)、次にデータフレームの数で割ります。 Reduce
を使用する必要があるのは、+
は一度に2つの引数しかとることができません(そして加算は結合法則です)。
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)
私は少し異なるアプローチを取ります:
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)]))
ネストされたlapply()
呼び出しを使用できませんか?
これは私のマシンで正しい結果を与えるようです
mean.dat <- lapply(all.dat, function (x) lapply(x, mean, na.rm=TRUE))