R数据表如果不存在,则为每个组添加行



我有一个包含多个组的数据表。我想用包含vals中的值的行填充每个组,如果它们还不存在的话。其他列应该用NAs填充。

DT = data.table(group = c(1,1,1,2,2,3,3,3,3), val = c(1,2,4,2,3,1,2,3,4), somethingElse = rep(1,9)) 
vals = data.table(val = c(1,2,3,4))

我想要的:

group val somethingElse
1:     1   1             1
2:     1   2             1
3:     1   3            NA
4:     1   4             1
5:     2   1            NA
6:     2   2             1
7:     2   3             1
8:     2   4            NA
9:     3   1             1
10:     3   2             1
11:     3   3             1
12:     3   4             1

val的顺序不一定是递增的,也可以出现在每一组的开头/结尾。

我不知道如何处理这个问题。我想过使用rbindlist(...,fill = TRUE),但随后的值将被简单地附加。我认为DT[, lapply(...), by = c("group")]的一些表达式可能在这里有用,但我不知道如何检查一个值是否已经存在。

您可以使用交叉连接:

setDT(DT)[
CJ(group = group, val = val, unique = TRUE), 
on = .(group, val)
]
group val somethingElse
1:     1   1             1
2:     1   2             1
3:     1   3            NA
4:     1   4             1
5:     2   1            NA
6:     2   2             1
7:     2   3             1
8:     2   4            NA
9:     3   1             1
10:     3   2             1
11:     3   3             1
12:     3   4             1

另一种解决问题的方法:

DT[, .SD[vals, on="val"], by=group]
group   val somethingElse
1:     1     1             1
2:     1     2             1
3:     1     3            NA
4:     1     4             1
5:     2     1            NA
6:     2     2             1
7:     2     3             1
8:     2     4            NA
9:     3     1             1
10:     3     2             1
11:     3     3             1
12:     3     4             1
# or
DT[CJ(group, val, unique=TRUE), on=.NATURAL]

对于稍微复杂一点的情况,我将添加以下答案:

#Raw Data
DT = data.table(group = c(1,1,2,2,2,3,3,3,3),
x = c(1,2,1,3,4,1,2,3,4),
y = c(2,4,2,6,8,2,4,6,8),
somethingElse = rep(1,9))
#allowed combinations of x and y
DTxy = data.table(x = c(1,2,3,4), y = c(2,4,6,8))

在这里,我想将DTxy中的所有x,y组合添加到DT中的每一组,如果还没有出现的话。

我写了一个用于子集的函数。

#function to join subsets on two columns (here: x,y)
DTxyJoin = function(.SD, xy){
.SD = .SD[xy, on = .(x,y)]
return(.SD)
}

然后将该函数应用于每组:

#add x and y to each group if missing
DTres = DT[, DTxyJoin(.SD, DTxy), by = c("group")]

结果:

group x y somethingElse
1:     1 1 2             1
2:     1 2 4             1
3:     1 3 6            NA
4:     1 4 8            NA
5:     2 1 2             1
6:     2 2 4            NA
7:     2 3 6             1
8:     2 4 8             1
9:     3 1 2             1
10:     3 2 4             1
11:     3 3 6             1
12:     3 4 8             1

最新更新