complete
сохраняет другие несвязанные столбцы, поэтому я добавлю один ...
library(data.table)
dt = data.table(
a = c(1,1,2,2,3,3,4,4) ,
b = c(4,5,6,7,8,9,10,11) ,
c = c("x","x","x","x","y","y","y","y"),
d = LETTERS[10 + 1:8])
a b c d
1: 1 4 x K
2: 1 5 x L
3: 2 6 x M
4: 2 7 x N
5: 3 8 y O
6: 3 9 y P
7: 4 10 y Q
8: 4 11 y R
Чтобы завершить комбинации аксб для каждого с, я бы создал новую таблицу с этими комбинациями (точно так же, какуже в ответе @ G.Grothendieck) и update-join, чтобы получить d и другие некомбинированные столбцы:
mDT = dt[, CJ(a = a, b = b, unique=TRUE), by=c]
cvars = copy(names(mDT))
ovars = setdiff(names(dt), cvars)
mDT[, (ovars) := dt[.SD, on=cvars, mget(sprintf("x.%s", ovars))]]
setcolorder(mDT, names(dt))
a b c d
1: 1 4 x K
2: 1 5 x L
3: 1 6 x <NA>
4: 1 7 x <NA>
5: 2 4 x <NA>
6: 2 5 x <NA>
7: 2 6 x M
8: 2 7 x N
9: 3 8 y O
10: 3 9 y P
11: 3 10 y <NA>
12: 3 11 y <NA>
13: 4 8 y <NA>
14: 4 9 y <NA>
15: 4 10 y Q
16: 4 11 y R
В качестве альтернативы, вы можете выполнить внутреннее (?) объединение, хотя это неэффективно, поскольку оно создаетдве новые таблицы:
dt[mDT, on=cvars]
# or more concisely....
dt[dt[, CJ(a = a, b = b, unique=TRUE), by=c], on=.(a,b,c)]
Или выполните одно внутреннее объединение для by=
группы (из @eddi):
dt[, .SD[CJ(a = a, b = b, unique = TRUE), on = .(a, b)], by = c]
Для сравнения в тидиверсе:
library(dplyr); library(tidyr)
data.frame(dt) %>% group_by(c) %>% complete(a, b)
# A tibble: 16 x 4
# Groups: c [2]
c a b d
<chr> <dbl> <dbl> <chr>
1 x 1 4 K
2 x 1 5 L
3 x 1 6 <NA>
4 x 1 7 <NA>
5 x 2 4 <NA>
6 x 2 5 <NA>
7 x 2 6 M
8 x 2 7 N
9 y 3 8 O
10 y 3 9 P
11 y 3 10 <NA>
12 y 3 11 <NA>
13 y 4 8 <NA>
14 y 4 9 <NA>
15 y 4 10 Q
16 y 4 11 R