2013-12-13 52 views
6

這裏是一個data.table:R:強制data.table計算所有交互

dat = data.table(var1=rnorm(120), var2=rep(c('a','b','c'),40), var3=rep(c(1,2,3,2,1,2,1,2,2,3,1,2),10)) 

dat2 = dat[,list(resp = mean(var1)),by=list(var2, var3)] 

dat2dat$var2等的唯一現有相互作用dat$var3都存在。我如何強制dat2var2var3包含所有9種可能的交互(而不是7行dat2)的結果?如果data.table沒有直接的解決方案,那麼解決這個問題最簡單的方法是什麼?

table(dat$var2, dat$var3) 

    1 2 3 
    a 20 10 10 
    b 20 20 0 
    c 0 30 10 

當然,對於其中在dat不存在數據的相互作用,dat2應包含在RESP NA。

+0

爲什麼不只是'data.table(...)'而不是'as.data.table(data.frame(...))'? – Arun

+0

沒理由,那真是愚蠢!我修好了它!謝謝 –

回答

6

您可以設置key,然後做在i像這樣使用CJ一個交叉連接...

setkey(dat , var2 , var3) 

# Thanks to @Shadow for pointing out to use unique() in the cross join 
dat[ CJ(unique(var2) , unique(var3)) , mean(var1) ] 
# var2 var3   V1 
#1: a 1 -0.25771923 
#2: a 2 0.04143057 
#3: a 3 0.28878451 
#4: b 1 0.18865887 
#5: b 2 0.53632552 
#6: b 3   NA 
#7: c 1   NA 
#8: c 2 0.38015021 
#9: c 3 0.49809159 

並通過解釋,CJ()創建在xi一個data.table(在這種情況下, dat)加入。它是作爲向CJ()提供的矢量的叉積而形成的,這恰好就是你正在尋找的!

+1

我同意'CJ'版本比我在下面提出的'expand.grid'更有意義。但是爲了一般性,我仍然認爲'dat [CJ(unique(var2),unique(var3)),mean(var1)]'比明確使用'letters [1:3]'和'1:3'更合適。 。 – shadow

+0

@shadow是的,你確定你完全正確,呼叫良好。 –