2016-06-29 5 views
1

可変列名を使用して、より速い行ごとのt.test結果を得るためにdata.tableの本来の速度を使用できますか?以下は私の現在のコードであり、1000行ごとに数秒かかる。R data.tableの各行にスピーディーなt.test

slow.diffexp <- function(dt, samples1, samples2) { 
    for (i in 1:nrow(dt)) { 
    if (round(i/1000)==i/1000) { 
     cat(i, "\n"); 
    } 
    a <- t.test(dt[i, samples1, with=FALSE], 
       dt[i, samples2, with=FALSE]); 
    set(dt, i, "tt.p.value", a$p.value) 
    set(dt, i, "tt.mean1", a$estimate[1]) 
    set(dt, i, "tt.mean2", a$estimate[2]) 
    } 
} 

test.dt <- data.table(V1=sample(1000, 100000, replace=TRUE)); 
for (i in 2:20) { 
    colname <- paste0("V", i); 
    test.dt[ , (colname):=sample(1000, 100000, replace=TRUE)]; 
} 
samples1 <- sample(names(test.dt), size=10); 
samples2 <- setdiff(names(test.dt), samples1); 
slow.diffexp(test.dt, samples1, samples2); 

私は以下の関連記事を見てきました:

- data.framesのために...

+1

'data.table'は通常、列単位の操作で高速です。 – lmo

+0

あなたが必要とする特定のものだけを行う 't.test.default'の独自のparedバージョンを作成すると、より多くのマイレージが得られるかもしれません。あるいは、p値のランダムなサンプルを単純に描くことができます。これはほとんど瞬間的です。 – joran

答えて

0

を。これは、明示的data.tableを使用しませんが、それがあるべきはるかに高速forループより:

set.seed(700) 
test.dt <- data.table(V1=sample(1000, 100000, replace=TRUE)); 
for (i in 2:20) { 
    colname <- paste0("V", i); 
    test.dt[ , (colname):=sample(1000, 100000, replace=TRUE)]; 
} 
samples1 <- sample(names(test.dt), size=10); 
samples2 <- setdiff(names(test.dt), samples1); 

system.time(myList<-apply(test.dt, 1, function(x) t.test(x[samples1], x[samples2]))) 
# user system elapsed 
# 18.44 0.00 18.47 

test.dt$tt.p.value<-sapply(myList, function(x) x[[3]]) 
test.dt$tt.mean1<-sapply(myList, function(x) x[[5]][[1]]) 
test.dt$tt.mean2<-sapply(myList, function(x) x[[5]][[2]]) 

test.dt[1:10, 19:23, with = F] 

V19 V20 tt.p.value tt.mean1 tt.mean2 
962 536 0.98203 460.8 463.9 
882 767 0.06294 657.4 416.0 
371 111 0.73440 463.1 502.8 
173 720 0.57195 595.9 513.3 
126 404 0.86948 602.8 619.5 
14 16 0.63462 315.7 377.3 
870 384 0.03670 377.7 626.6 
142 997 0.19836 623.2 442.8 
    4 193 0.99891 628.4 628.2 
250 888 0.35232 590.9 498.5 

他の方法は、約10倍遅くなります(少し長い時間で、1/10の仕事ん)

system.time(slow.diffexp(test.dt[1:10000], samples1, samples2)) 
# user system elapsed 
# 22.12 0.00 22.17