Reputation: 173
I have a data.table
like:
DT = data.table(ColumnA = c(1.51, 1.86, 3.54, 3.79, 7.7))
I am trying to create ColumnB
which holds the next value of ColumnA
:
columnA ColumnB
1.51 1.86
1.86 3.54
3.54 3.79
3.79 7.70
7.70
I tried the following and it was working, however now it is not working:
``` DT[, ColumnB:=c(NA,ColumnA[.I + 2]) ]```
I am getting this error:
Error in .Call() : Supplied 18391 items to be assigned to 18390 items of column 'ColumnB'. If you wish to 'recycle' the RHS please use rep() to make this intent clear to readers of your code.
Upvotes: 2
Views: 130
Reputation: 34703
It looks like you're writing data.table
code, so you're in luck! The shift
function is what you're after:
DT[ , ColumnB := shift(ColumnA, type = 'lead')]
Since you're doing some analysis with shift
, be sure to also see the other related functions data.table
has to offer: nafill
, frollsum
/frollmean
/froll
, etc.
As to why your code is not working:
c(NA, ColumnA[.I + 2])
The first element is NA
; the next is a vector subset of ColumnA
at indices .I+2
. .I + 2
is all of the elements of .I
, shifted up by 2
. .I
has the same length as ColumnA
, so ColumnA[.I + 2]
will also have the same length as ColumnA
-- hence c(NA, ColumnA[.I + 2])
has one more element than ColumnA
.
That's why you see the off-by-one note in your error:
Supplied 18391 items to be assigned to 18390 items
If you wanted to do a subset approach (which will be slower), you could do:
DT[ , ColumnA := c(NA, ColumnA[-1L])]
ColumnA[-1L]
is ColumnA
, minus the first element, hence there are one fewer elements than are in ColumnA
and when we combine with NA
, we have the right number.
Upvotes: 5