2013-12-13 41 views
6

hesaplamak için data.table zorla bir data.table olup: dat$var2 etR: Burada tüm etkileşimler

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)] 

dat2 olarak, sadece var olan etkileşimleri dat$var3 bulunmaktadır. dat2'u, var2 ve var3 için 9 olası etkileşimin (7 satırlık dat2 yerine) sonuçları içerecek şekilde nasıl zorlayabilirim? Data.table ile doğrudan bir çözüm yoksa, bu sorunu çözmenin en kolay yolu nedir?

table(dat$var2, dat$var3) 

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

Tabii ki, herhangi bir veri dat mevcut etkileşimler için, dat2 resp NA içermelidir.

+0

Neden "data.table (...)" yerine "as.data.table (data.frame (...))' yerine değil? – Arun

+0

Bunun bir nedeni, bu aptaldı! Onardım! Teşekkür ederim –

cevap

6

Sen

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 

Ve açıklaması yoluyla

, CJ() bu durumda ( x arasında i bir data.table yaratır ... şöyle i yılında CJ kullanarak Crossjoin yapmak sonra key ayarlamak ve olabilir Katılmak için dat). Tam olarak aradığınız şey olan CJ()'a verilen vektörlerin çapraz ürünü olarak oluşturulmuştur!

+1

"CJ" sürümünün aşağıda önerdiğim "expand.grid" den daha anlamlı olduğunu kabul ediyorum. Ama genellenebilirlik için hala şunu düşünüyorum: “dat [CJ (benzersiz (var2), benzersiz (var3)), ortalama (var1)]' 'harfleri [1: 3]' ve '1: 3'ü açıkça kullanmaktan daha uygun olurdu. . – shadow

+0

@shadow Evet, kesinlikle haklısınız, iyi bir çağrı. –