1

私は大きな行列を持っています。目標は、列1、2、および3ですべて等しい値を持つすべての行を認識し、行の各セットの4番目の列で0のパーセンテージを計算することです。このすべてのパーセンテージを「データ」と呼ばれるベクトルに入れます。次に、列の共通値を記録する3つのベクトル(列ごと(最後の列を除く))が必要です。これらのベクトルを、列1、2、および3に対してそれぞれ「factor1」、「factor2」、および「factor3」と呼びます。私の行列は大きくて多数なので、計算するには高速で効率的なものが必要です。

たとえば、私はこのマトリックスを持っています:

    [,1][,2][,3][,4]
[1,]  1    1   1   0
[2,]  1    2   1   0
[3,]  3    2   1   0.6
[4,]  1    1   1   0.2
[5,]  1    2   1   0
[6,]  1    1   2   0.1
[7,]  3    2   1   0.9

ここでは、行1と4をグループ化して(列1、2、3の等しい値に基づいて)、0のパーセンテージを計算します(列4)(%zeroは0.5に等しい)

次に、行2と5をグループ化し、%zero(1に等しい)を再度計算します。

次に、行3と7をグループ化し、%zero(0に等しい)を計算します。

次に、行6は単独で、その%zero(0に等しい)

これが私が取得したいベクトルです:

> data = c(0.5,1,0,0)

> factor1 = c(1,1,3,1)

> factor2 = c(1,2,2,1)

> factor3 = c(1,1,1,2)

これらの値の順序は重要ではありません。ベクトル「data」の値0.5が位置2にある場合、すべての要素の位置2は1になります。

次に、次のaovを実行することが目標です。

> aov(data ~ factor1 * factor2 * factor3)

あなたの助けをどうもありがとう

4

3 に答える 3

2

行列が非常に大きい場合は、data.table に変換する際のコストを含めることを忘れないでください。以下はかなり速いはずです。

colnames(m) <- c(paste0('factor', 1:3), 'data')
aggregate(data ~ ., data = m, function(x) mean(x!=0))

それでも私はそれをテストしましたが、plyr は実際にはここで data.table とかなり競争力があり、集計はかなり遅れていることがわかりました (3x)。最近のバージョンの plyr (1.8) は、以前よりもはるかに高速になりました。

いくつかのテストでは、最初に data.frame に変換すると (data.frame の変換時間を含めても)、集計がはるかに高速 (2 倍) になることがわかりました。

投稿された回答はどれも本当に遅いものではありません。これらのマトリックスがたくさんある場合、それらはファイルにあると思います。コードが非常に遅い場合は、そこにボトルネックがあると思います。ファイルからの行列の読み取りを最適化する方法があります (scanの代わりに使用read.table)

(余談ですが、おそらくこのデータに対して ANOVA を実行するべきではありません)

于 2013-03-04T12:24:15.590 に答える
2

マトリックスを再作成します。

df <- read.table(text="[,1] [,2] [,3] [,4]
[1,]  1    1   1   0
[2,]  1    2   1   0
[3,]  3    2   1   0.6
[4,]  1    1   1   0.2
[5,]  1    2   1   0
[6,]  1    1   2   0.1
[7,]  3    2   1   0.9",header=TRUE)
m <- as.matrix(df)
colnames(m) <- NULL

パッケージ data.table を使用して分割適用結合します。data.table は、その効率性から巨大なデータセットに推奨されます。

library(data.table)
DT <- as.data.table(m)

DT.agg <- DT[,sum(V4==0)/length(V4),by=list(V1,V2,V3)]
setnames(DT.agg,c("factor1","factor2","factor3","data"))
print(DT.agg)
#   factor1 factor2 factor3 data
#1:       1       1       1  0.5
#2:       1       2       1  1.0
#3:       3       2       1  0.0
#4:       1       1       2  0.0

aov(data ~ factor1 * factor2 * factor3, data = DT.agg)
于 2013-03-04T10:04:36.877 に答える
0

これがパッケージによる解決策plyrです。あなたmのマトリックスの場合:

m <- data.frame(m)
colnames(m) <- c("V1","V2","V3","data")
m2 <- ddply(m, .(V1,V2,V3), summarise, data=sum(data==0)/length(data))

与える:

  V1 V2 V3 data
1  1  1  1  0.5
2  1  1  2  0.0
3  1  2  1  1.0
4  3  2  1  0.0

その後、次のことができます。

aov(data=m2, data ~ V1 * V2 * V3)

plyrただし、常に最速のソリューションとは限りません。

于 2013-03-04T10:10:02.493 に答える