2013-06-04 47 views
0

我在data.table上遇到了一個我不明白的錯誤。我想要做的是執行多個t.test作爲事後分析。因此,這裏的一些樣本數據:長格式的data.table中的t.test

dt <- data.table(
    expand.grid(list(SID = rep(paste0("x", 1:3), 3), MID = paste0("y", 1:5)), stringsAsFactors=FALSE), 
    A = rnorm(45), 
    key = c("SID") 
) dt 

    SID MID   A 
1: x1 y1 -1.4451214 
2: x1 y2 -0.6141025 
3: x1 y3 -1.0388595 
4: x1 y4 -0.8098261 
... 

這給了我那麼奇怪的錯誤:

dt[ , list(t.test(x=.SD[ J("x1"), A ], y=.SD[ J("x2"), A ])$p.value) , by = MID ] 
Error in setkey(ans, NULL) : 
    x may no longer be the character name of the data.table. The possibility was undocumented and has been removed. 

我不知道這意味着什麼,但所需的輸出會像

MID p.x1.x2 
1: y1 0.1 
2: y2 0.2 
3: y3 0.3 
4: y4 0.4 
5: y5 0.5 

這就是我最終能夠做到的(只是爲了給你全圖):

combinations <- lapply(as.data.frame(combn(unique(dt$SID), 2), stringsAsFactors=FALSE), identity) 
combinations 
$V1 
[1] "x1" "x2" 

$V2 
[1] "x1" "x3" 

$V3 
[1] "x2" "x3"  

test.tab <- lapply(combinations, function(.sid, .dt){ 
    dt[ , list(t.test(x=.SD[ J(.sid[1]), A ], y=.SD[ J(.sid[2]), A ])$p.value) , by = MID ] 
}, .dt = dt) 
test.tab <- as.data.table(as.data.frame(test.tab)) 

任何想法如何避免錯誤,表示讚賞。任何其他方法來獲得相同的結果也會很好。

+2

您尚未爲data.table設置密鑰。你需要使用'J(。)'。無論如何,我認爲你要找的是:'dt [,list(t.test(x = A [SID ==「x1」],y = A [SID ==「x2」])$ p .value),by = MID](在這種情況下,只會返回一個錯誤,表示沒有足夠的值)。 – Arun

+0

@阿倫感謝,確實還有兩個錯誤:1)每個組合SID/MID只有一個觀察值2)我忘記選擇't.test'中的相應列,因此它已經被't.test x = .SD [J(「x1」),A],y = .SD [J(「x2」),A])''。我以我的例子解決了這個問題。如果現在有更好的答案,你的解決方案可以正常工作。但是我不明白:當'dt'定義爲'SID'時,我確實設置了密鑰。那麼爲什麼在'.SD'中沒有考慮到這一點。那錯誤是什麼意思? – Beasterfield

+1

Beasterfield,'。SD [J(「x1」),A]'仍然會給出一個'data.table'。如果你真的想要使用'.SD',你應該怎麼做才能給出一個向量:'.SD [J(「x1」)] [,A]'。也就是說,你應該這樣做:'dt [,t.test(.SD [J(「x1」)] [,A],.SD [J(「x2」)] [,A])$ p.value, by = MID]'。 – Arun

回答

1

誤差來源於此行t.test.default

y <- y[yok] 

Error in setkey(ans, NULL) : 
    x may no longer be the character name of the data.table. The possibility was undocumented and has been removed. 

可以打印屏幕上的功能與stats:::t.test.default(這是什麼運行的t.test的版本)。

這裏,y預計會爲你提供.SD[J("x1"), A]這是一個data.table當載體(如我在評論中提到)。

在你的情況,yok計算結果爲:

 SID A 
[1,] TRUE TRUE 
[2,] TRUE TRUE 
[3,] TRUE TRUE 
[4,] TRUE TRUE 
[5,] TRUE TRUE 
[6,] TRUE TRUE 
[7,] TRUE TRUE 
[8,] TRUE TRUE 
[9,] TRUE TRUE 
[10,] TRUE TRUE 
[11,] TRUE TRUE 
[12,] TRUE TRUE 
[13,] TRUE TRUE 
[14,] TRUE TRUE 
[15,] TRUE TRUE 

y是:

SID   A 
1: x2 -0.80390040 
2: x2 0.34483953 
3: x2 2.08006382 
4: x2 0.87859745 
5: x2 1.04123702 
6: x2 0.13653716 
7: x2 0.58482554 
8: x2 -0.78308074 
9: x2 -0.02177879 
10: x2 -0.33626948 
11: x2 0.17005957 
12: x2 1.15227502 
13: x2 1.21486699 
14: x2 0.93856469 
15: x2 -0.54720535 

而且做y[yok]會給你這個錯誤爲 「Y」 的鍵值設置爲「SID 」。

簡而言之,你被要求爲x和y參數提供一個向量值,而你提供一個data.table,並且因爲它與列「SID」相關,並且它在內部運行y[yok]這是兩列,錯誤發生在那裏。如果你改爲:as.data.frame(.SD[J("x1"), A])那麼你會發現這個錯誤會消失,但是你仍然會得到一些其他的錯誤(這個錯誤消失了,因爲沒有「關鍵」問題)。

這樣做:

debugonce(stats:::t.test.default) 
t.test(dt["x1", A], dt["x2", A]) 

,並保持打擊 「進入」 到明白我的意思。

+0

非常感謝你提供'debugonce'的詳細解釋。 – Beasterfield