R datatable:向所有组添加观察值,并根据其他行分配值
假设我们有一个带有ID和子组的data.table,如下所示: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高效地实现这一点?我提出的唯一解决方案是重新塑造
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)