3

次のディメンションのデータフレームがあります。

dim(b)  
[1]    974 433685

列は、ANOVA を実行したい (つまり、433,685 の ANOVA を実行したい) 変数を表します。サンプルサイズは 974 です。最後の列は「グループ」変数です。

私は3つの異なる方法を思いつきましたが、テストの数が原因ですべてが遅すぎます.

まず、小さな練習用データセットを生成して遊んでみましょう。

dat = as.data.frame(matrix(runif(10000*500), ncol = 10000, nrow = 500))
dat$group = rep(letters[1:10], 5000)

方法 1 ( 'sapply'に基づく):

system.time(sapply(dat[,-length(dat)], function(x) aov(x~group, data=dat) ))

   user  system elapsed 
 143.76    0.33  151.79 

方法 2 (「parallel」パッケージの「mclapply」に基づく):

library(parallel)
options(mc.cores=3)
system.time(mclapply(dat[,-length(dat)], function(x) aov(x~group, data=dat) ))

   user  system elapsed 
 141.76    0.21  142.58 

方法 3 ( LHS の「cbind」に基づく):

formula = as.formula( paste0("cbind(", paste(names(dat)[-length(dat)],collapse=","), ")~group") ) 
system.time(aov(formula, data=dat))

  user  system elapsed 
  10.00    0.22   10.25 

実践データセットでは、方法 3 が明らかに勝者です。ただし、実際のデータでこれを行うと、方法 3 を使用して 10 (433,685) 列だけを計算すると、次のように時間がかかります。

   user  system elapsed
119.028   5.430 124.414

実際のデータでかなり時間がかかる理由がわかりません。16 個以上のコアと 72 GB の RAM を搭載した Linux クラスターにアクセスできます。

これをより速く計算する方法はありますか?

4

1 に答える 1

2

同じ計画行列を使用して多くの一般的な線形モデル (ANOVA など) を同時にフィッティングするために、Bioconductor/R limma パッケージは非常に高速な lmFit() 関数を提供します。これは、limma を使用して ANOVA モデルを適合させる方法です。

library(limma)

# generate some data 
# (same dimensions as in your question)
nrows <- 1e4
ncols <- 5e2
nlevels <- 10
dat <- matrix(
  runif(nrows * ncols), 
  nrow = nrows, 
  ncol = ncols
)
group <- factor(rep(
  letters[1:nlevels], 
  ncols / nlevels
))

# construct the design matrix
# (same as implicitly used in your question)
dmat <- model.matrix(~ group)
# fit the ANOVA model
fit <- lmFit(dat, dmat)

私のラップトップでは、質問のデータと同じ次元のデータで、0.4 - 0.45 秒で終了しました。

于 2016-12-21T12:09:20.577 に答える