这就是我的数据表:
library(data.table)
dt <- fread('
Product Group LastProductOfPriorGroup
A 1 NA
B 1 NA
C 2 B
D 2 B
E 2 B
F 3 E
G 3 E
')
LastProductOfPriorGroup
列是我想要的列。我正在尝试从前一组的最后一行获取产品。因此,在前两行中,没有先前的组,因此它是NA
。在第三行中,前一组1的最后一行中的产品是B
。我试图通过
dt[,LastGroupProduct:= shift(Product,1), by=shift(Group,1)]
无济于事。
答案 0 :(得分:14)
你可以做到
dt[, newcol := shift(dt[, last(Product), by = Group]$V1)[.GRP], by = Group]
这会导致以下更新dt
,其中newcol
与您想要的列匹配不必要的长名称。 ;)
Product Group LastProductOfPriorGroup newcol
1: A 1 NA NA
2: B 1 NA NA
3: C 2 B B
4: D 2 B B
5: E 2 B B
6: F 3 E E
7: G 3 E E
让我们从内到外打破代码。我将使用...
来表示累积的代码:
dt[, last(Product), by = Group]$V1
将每组中的最后一个值作为字符向量。 shift(...)
移动上一次调用中的字符向量dt[, newcol := ...[.GRP], by = Group]
分组Group
并使用内部.GRP
值进行索引更新:Frank为我的代码提出了一个很好的观点,一遍又一遍地计算每个组的班次。为避免这种情况,我们可以使用
shifted <- shift(dt[, last(Product), Group]$V1)
dt[, newcol := shifted[.GRP], by = Group]
这样我们就不会计算每个组的班次。或者,我们可以在评论中采纳弗兰克的好建议并执行以下操作。
dt[dt[, last(Product), by = Group][, v := shift(V1)], on="Group", newcol := i.v]