Here is a 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)]

In dat2, only existing interactions of dat$var2 et dat$var3 are present. How can I force dat2 to contain results for all 9 possible interactions (instead of the 7 rows of dat2) for var2 and var3? If there is no direct solutions with data.table, what is the easiest way to solve this issue?

table(dat$var2, dat$var3)

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

Of course, for the interactions where no data exist in dat, dat2 should contain NA in resp.

有帮助吗?

解决方案

You could set the key and then do a crossjoin using CJ in the i like so...

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

And by way of explanation, CJ() creates a data.table in the i of x (in this case dat) to join on. It is formed as the cross product of the vectors supplied to CJ(), which happens to be precisely what you are looking for!

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top