2012-07-12 10 views
6

Büyük bir matris olduğunu varsayalım. Her bir sütuna t.test() uygulamak istediğimi söyle, bunu apply() kullanmanınkinden daha hızlı bir şekilde yapmak için bir yol var mı?Büyük bir matrisin her sütununa t.test uygulamanın en hızlı yolu nedir?</p> <pre><code>M <- matrix(rnorm(1e7),nrow=20) </code></pre> <p>ayrıntılı her sütun bir örneğini temsil eder olduğunu varsayalım:

apply(M, 2, t.test) 

Benim bilgisayarda analiz çalışmasına biraz az 2 dakika sürdü:

> system.time(invisible(apply(M, 2, t.test))) 
user system elapsed 
113.513 0.663 113.519 
+0

'apply' çok esnek bir işlevdir ve bu nedenle, herhangi bir durumda gerek duymadığınız birçok şeyi içerir. Muhtemelen 'for' döngüsü ile manuel olarak aynı mantığı kodlamak bazı performans artışı verecektir. – ffriend

cevap

8

Bir çok çekirdekli makinen varsa mclapply kullanarak örneğin, tüm çekirdekleri kullanarak bazı kazançlar vardır.

> library(multicore) 
> M <- matrix(rnorm(40),nrow=20) 
> x1 <- apply(M, 2, t.test) 
> x2 <- mclapply(1:dim(M)[2], function(i) t.test(M[,i])) 
> all.equal(x1, x2) 
[1] "Component 1: Component 9: 1 string mismatch" "Component 2: Component 9: 1 string mismatch" 
# str(x1) and str(x2) show that the difference is immaterial 

Bu mini örnek, planların planlandığı gibi devam ettiğini gösterir. Şimdi ölçeklendirin:

8 sanal çekirdek kullanıyor. Yolculuğunuz değişebilir. Büyük bir kazanç değil, ama çok az çabadan geliyor.

DÜZENLEME yalnızca ilgili alanı ($statistic) ayıklanması, t istatistiğinin kendisi önem veriyorsanız

çok çekirdekli durumunda özellikle biraz daha hızlı şeyler yapar:

> system.time(invisible(apply(M, 2, function(c) t.test(c)$statistic))) 
    user system elapsed 
80.920 0.437 82.109 
> system.time(invisible(mclapply(1:dim(M)[2], function(i) t.test(M[,i])$statistic))) 
    user system elapsed 
21.246 1.367 24.107 

Ya daha da hızlı, doğrudan

my.t.test <- function(c){ 
    n <- sqrt(length(c)) 
    mean(c)*n/sd(c) 
} 

Sonra

01 ton değerini hesaplamak
> system.time(invisible(apply(M, 2, function(c) my.t.test(c)))) 
    user system elapsed 
21.371 0.247 21.532 
> system.time(invisible(mclapply(1:dim(M)[2], function(i) my.t.test(M[,i])))) 
    user system elapsed 
144.161 8.658 6.313 
+0

Sanırım t istatistiklerini direkt olarak hesaplayacağım, gösterdiğiniz gibi, çok daha hızlı. – Alex

8

Sen (Bioconductor üzerine) genefilter paketinden colttests fonksiyonu ile bundan daha iyisini yapabiliriz.

> library(genefilter) 
> M <- matrix(rnorm(40),nrow=20) 
> my.t.test <- function(c){ 
+ n <- sqrt(length(c)) 
+ mean(c)*n/sd(c) 
+ } 
> x1 <- apply(M, 2, function(c) my.t.test(c)) 
> x2 <- colttests(M, gl(1, nrow(M)))[,"statistic"] 
> all.equal(x1, x2) 
[1] TRUE 
> M <- matrix(rnorm(1e7), nrow=20) 
> system.time(invisible(apply(M, 2, function(c) my.t.test(c)))) 
    user system elapsed 
27.386 0.004 27.445 
> system.time(invisible(colttests(M, gl(1, nrow(M)))[,"statistic"])) 
    user system elapsed 
    0.412 0.000 0.414 

Ref: "eş zamanlı olarak R test istatistik Bilgisayar binlerce", SCGN, Cilt 18 (1), 2007 http://stat-computing.org/newsletter/issues/scgn-18-1.pdf.

+0

(+1) Bilmekte fayda var, referans için teşekkürler. – chl

+0

Bilmekte fayda var. Teşekkürler!! – Alex

İlgili konular