You could do
dt[, newcol := shift(dt[, last(Product), by = Group]$V1)[.GRP], by = Group]
This results in the following updated dt
, where newcol
matches your desired column with the unnecessarily long name. ;)
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
Let's break the code down from the inside out. I will use ...
to denote the accumulated code:
dt[, last(Product), by = Group]$V1
is getting the last values from each group as a character vector.
shift(...)
shifts the character vector in the previous call
dt[, newcol := ...[.GRP], by = Group]
groups by Group
and uses the internal .GRP
values for indexing
Update: Frank brings up a good point about my code above calculating the shift for every group over and over again. To avoid that, we can use either
shifted <- shift(dt[, last(Product), Group]$V1)
dt[, newcol := shifted[.GRP], by = Group]
so that we don't calculate the shift for every group. Or, we can take Frank's nice suggestion in the comments and do the following.
dt[dt[, last(Product), by = Group][, v := shift(V1)], on="Group", newcol := i.v]
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…