Пустые факторы в "по" data.table

У меня есть data.table, который имеет столбец факторов с пустыми уровнями. Мне нужно получить счетчик строк и суммы других переменных, все сгруппированные по нескольким факторам, в том числе с пустыми уровнями. Мой вопрос похож на этот один, но здесь мне нужно учитывать несколько факторов.

Например, пусть data.table будет:

library('data.table')

dtr <- data.table(v1=sample(1:15), 
v2=factor(sample(letters[1:3], 15, replace = TRUE),levels=letters[1:5]),
v3=sample(c("yes", "no"), 15, replace = TRUE))

Я хочу сделать следующее:

dtr[,list(freq=.N,mm=sum(v1,na.rm=T)),by=list(v2,v3)]

#Output is:
   v2  v3 freq mm
1:  b yes    4 22
2:  b  no    1 13
3:  c  no    3 10
4:  a  no    4 49
5:  c yes    1 10
6:  a yes    2 16

Я хочу, чтобы вывод включал пустые уровни для v2 ( "d" и "e" ), как в table(dtr$v2,dtr$v3), поэтому окончательный вывод должен выглядеть (порядок не имеет значения):

   v2  v3 freq mm
1:  b yes    4 22
2:  b  no    1 13
3:  c  no    3 10
4:  a  no    4 49
5:  c yes    1 10
6:  a yes    2 16
7:  d yes    0 0
8:  d no    0 0
9:  e yes    0 0
10:  e no    0 0

Я попытался использовать метод, используемый в ссылке, но я не уверен, как использовать совместную функцию J() при использовании нескольких столбцов.

Это отлично подходит для группировки только на 1 столбец:

setkey(dtr,v2)
dtr[J(levels(v2)),list(freq=.N,mm=sum(v1,na.rm=T))]

Однако dtr[J(levels(v2),v3),list(freq=.N,mm=sum(v1,na.rm=T))] не включает все комбинации

Ответ 1

library(data.table)
set.seed(42)
dtr <- data.table(v1=sample(1:15), 
                  v2=factor(sample(letters[1:3], 15, replace = TRUE),levels=letters[1:5]),
                  v3=sample(c("yes", "no"), 15, replace = TRUE))

res <- dtr[,list(freq=.N,mm=sum(v1,na.rm=T)),by=list(v2,v3)]

Вы можете использовать CJ (кросс-соединение). Выполнение этого после агрегации позволяет избежать установки ключа для большой таблицы и должно быть быстрее.

setkeyv(res,c("v2","v3"))
res[CJ(levels(dtr[,v2]),unique(dtr[,v3])),]

#    v2  v3 freq mm
# 1:  a  no    1  9
# 2:  a yes    2 11
# 3:  b  no    2 11
# 4:  b yes    3 23
# 5:  c  no    4 40
# 6:  c yes    3 26
# 7:  d  no   NA NA
# 8:  d yes   NA NA
# 9:  e  no   NA NA
# 10:  e yes   NA NA