web-dev-qa-db-ja.com

data.framesのリスト内の要素の平均

(行と列が等しい)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などの最初の行と最初の列の平均)オン)? lapplyldplyplyrを試しましたが、これらはリスト内の各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

これを行うためのより不格好でより速い方法があるかどうか疑問に思いました。ありがとう!

23
ChrisC

これがplyrのワンライナーです。 meanを他の任意の関数に置き換えることができます。

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

abindライブラリを使用して)3つの2次元行列を1つの3次元配列に結合することで、データ構造を簡単に変更できます。次に、applyを使用し、平均化するディメンションを指定することで、ソリューションはより直接的になります。

編集:

質問に答えたとき、それはhomeworkとタグ付けされていたので、私はただアプローチをしました。元のポスターはそのタグを削除したので、そうではないという彼/彼女の言葉で彼/彼女を連れて行きます。

library("abind")

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

結果を達成するために完全に異なるデータ構造を使用する1つの答えを与えました。この回答では、直接指定されたデータ構造(データフレームのリスト)を使用します。あまりエレガントではないと思いますが、とにかく提供したかったのです。

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

ロジックは、データフレームを要素ごとに追加することです(これは+はデータフレームで行います)、次にデータフレームの数で割ります。 Reduceを使用する必要があるのは、+は一度に2つの引数しかとることができません(そして加算は結合法則です)。

10
Brian Diggs

base関数のみを使用してオブジェクトの構造を変更する別のアプローチ:

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

これで、meanrowMeansで計算したり、medianapplyで計算したりできます。

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

私は少し異なるアプローチを取ります:

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)]))
2

ネストされたlapply()呼び出しを使用できませんか?

これは私のマシンで正しい結果を与えるようです

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