Использовать значение из предыдущей строки в данных R.таблица расчета
Я хочу создать новый столбец в данные.таблица рассчитывается из текущего значения одного столбца и предыдущего другого. Можно ли получить доступ к предыдущим строкам?
например:
> DT <- data.table(A=1:5, B=1:5*10, C=1:5*100)
> DT
A B C
1: 1 10 100
2: 2 20 200
3: 3 30 300
4: 4 40 400
5: 5 50 500
> DT[, D := C + BPreviousRow] # What is the correct code here?
правильный ответ должен быть
> DT
A B C D
1: 1 10 100 NA
2: 2 20 200 210
3: 3 30 300 320
4: 4 40 400 430
5: 5 50 500 540
7 ответов:
С
shift()
реализовала в В1.9.6, это достаточно просто.DT[ , D := C + shift(B, 1L, type="lag")] # or equivalently, in this case, DT[ , D := C + shift(B)]
С новости:
- новая функция
shift()
реализует fastlead/lag
на вектор,список,данные.кадры или данные.таблицы. Это занимаетtype
аргумент, который может быть либо "отставание" (по умолчанию) или "вести". Это позволяет очень удобное использование вместе с:=
илиset()
. Например:DT[, (cols) := shift(.SD, 1L), by=id]
. Пожалуйста, взгляните на?shift
для получения дополнительной информации.
смотрите историю для предыдущих ответов.
несколько человек ответили на конкретный вопрос. См. код ниже для функции общего назначения, которую я использую в таких ситуациях, которые могут быть полезны. Вместо того, чтобы просто получить предыдущую строку, вы можете пройти столько строк в "прошлом" или "будущем", сколько захотите.
rowShift <- function(x, shiftLen = 1L) { r <- (1L + shiftLen):(length(x) + shiftLen) r[r<1] <- NA return(x[r]) } # Create column D by adding column C and the value from the previous row of column B: DT[, D := C + rowShift(B,-1)] # Get the Old Faithul eruption length from two events ago, and three events in the future: as.data.table(faithful)[1:5,list(eruptLengthCurrent=eruptions, eruptLengthTwoPrior=rowShift(eruptions,-2), eruptLengthThreeFuture=rowShift(eruptions,3))] ## eruptLengthCurrent eruptLengthTwoPrior eruptLengthThreeFuture ##1: 3.600 NA 2.283 ##2: 1.800 NA 4.533 ##3: 3.333 3.600 NA ##4: 2.283 1.800 NA ##5: 4.533 3.333 NA
используя
dplyr
вы могли бы сделать:mutate(DT, D = lag(B) + C)
что дает:
# A B C D #1: 1 10 100 NA #2: 2 20 200 210 #3: 3 30 300 320 #4: 4 40 400 430 #5: 5 50 500 540
основываясь на комментарии @Steve Lianoglou выше, почему бы просто не:
DT[, D:= C + c(NA, B[.I - 1]) ] # A B C D # 1: 1 10 100 NA # 2: 2 20 200 210 # 3: 3 30 300 320 # 4: 4 40 400 430 # 5: 5 50 500 540
и избегать использования
seq_len
илиhead
или любая другая функция.
после решения Аруна, аналогичные результаты могут быть получены без ссылки на
.N
> DT[, D := C + c(NA, head(B, -1))][] A B C D 1: 1 10 100 NA 2: 2 20 200 210 3: 3 30 300 320 4: 4 40 400 430 5: 5 50 500 540
Я добавил аргумент заполнения и изменил некоторые имена и назвал его
shift
. https://github.com/geneorama/geneorama/blob/master/R/shift.R
вот мое интуитивное решение:
ваш фрейм данных
df=данные.кадр (A=1: 5, B=seq (10,50,10), C=seq(100,500, 100))
Теперь создайте новый столбец
df$D=c (NA, head(df$B, 4)+tail(df$C, 4))
здесь 4-это число строк минус 1. Если у вас есть, скажем, 1000 строк, то 4 должны быть заменены на 999. nrow (df) предоставляет вам количество строк во фрейме данных или в векторе. Аналогично, если вы хотите взять еще более ранние значения, вычтите из nrow 2, 3, ...и т. д., а также поставить NA соответственно в начале. Надеюсь, это поможет.