Firstly, the development version on GitHub already has an effective shift delay function, which can be used both as a lag and as a leader (and also has some additional functions, see ?shift ).
Take also here , as there are tons of other new features that are now present in v> = 1.9.5
So, with v> = 1.9.5 we could just do
foo[, quality_lag := shift(quality), by = group]
Although even with v <1.9.5 you can use .N instead of creating this function as follows
foo[, quality_lag2 := c(NA, quality[-.N]), by = group]
As for your second question, I would recommend avoiding ifelse all together for many reasons mentioned here
A possible alternative would be simple indexing, as in
foo[, quality_1 := quality][quality == 'low' & quality_lag == 'high', quality_1 := "high"]
This solution has several overheads by calling [.data.table twice, but it will be much more efficient / secure than ifelse solution.
source share