R datatable:向所有组添加观察值,并根据其他行分配值

R datatable:向所有组添加观察值,并根据其他行分配值,r,data.table,data-management,R,Data.table,Data Management,假设我们有一个带有ID和子组的data.table,如下所示: DT <- data.table(id=c("A","A","B","B"), subgroup=c("k","m","k","m"), C=c(4,9,6,5)) > DT id subgroup C 1: A k 4 2: A m 9 3: B k 6 4: B m 5 如何使用data.table高效地实现这一点?我提出的唯一解决方案是重新塑造

假设我们有一个带有ID和子组的data.table,如下所示:

DT <- data.table(id=c("A","A","B","B"), subgroup=c("k","m","k","m"), C=c(4,9,6,5))
> DT
   id subgroup C
1:  A        k 4
2:  A        m 9
3:  B        k 6
4:  B        m 5
如何使用data.table高效地实现这一点?我提出的唯一解决方案是重新塑造为宽,然后创建新的列;但是如果有一个大的ID集,这将是相当笨拙的

注意:在实际应用程序中,会有更多的子组和ID

更新以考虑到具有两个以上子组的复杂情况

您可以执行以下操作:

# add a new row in each group based on given condition
DT <- rbind(DT, DT[,.SD,id][,`:=`(subgroup = 'l', C = C/2)])

# order the data by id
DT <- DT[order(id)]

谢谢,但如果有两个以上的子组,这将不起作用,对吗?C/2必须以子组k为条件。您可以使用
copy(.SD)
而不是
DT[,.SD,id]
@Luks你可以在那里使用
.SD[subgroup==“k”]
,是的。@Frank对不起,但我不明白,你能再解释一下吗?对不起,我的意思是
res=DT[,rbind(.SD,copy(.SD)[,`:=`(subgroup='l',C=C/2)];setorder(res,id)
(这只是做你已经做过的事情的另一种方式)。对于Luks的扩展
res=DT[,rbind(.SD,.SD[子组==“k”][,`:=`(子组='l',C=C/2)]);setorder(res,id)
(用
DT覆盖)也许您可以在开始的示例中添加第二个子组,以确保得到能够处理实际问题复杂性的答案。
# add a new row in each group based on given condition
DT <- rbind(DT, DT[,.SD,id][,`:=`(subgroup = 'l', C = C/2)])

# order the data by id
DT <- DT[order(id)]
DT[, rbind(.SD, copy(.SD)[,`:=`(subgroup = 'l', C = C/2)])]
setorder(res, id)