Используйте значение из предыдущей строки в расчете R.table.table
Я хочу создать новый столбец в таблице данных, рассчитанный из текущего значения одного столбца и предыдущего. Возможно ли доступ к предыдущим строкам?
например:.
> 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
Ответы
Ответ 1
С shift()
, реализованным в v1.9.6, это довольно просто.
DT[ , D := C + shift(B, 1L, type="lag")]
# or equivalently, in this case,
DT[ , D := C + shift(B)]
Из НОВОСТИ:
- Новая функция
shift()
реализует быстрый lead/lag
вектор, список, data.frames или data.tables. Он принимает аргумент type
, который может быть либо "отставанием" (по умолчанию), либо "ведущим". Это позволяет очень удобно использовать вместе с :=
или set()
. Например: DT[, (cols) := shift(.SD, 1L), by=id]
. Пожалуйста, посмотрите ?shift
для получения дополнительной информации.
См. историю предыдущих ответов.
Ответ 2
Используя 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
Ответ 3
Несколько человек ответили на конкретный вопрос. См. Приведенный ниже код для функции общего назначения, которую я использую в таких ситуациях, которые могут быть полезны. Вместо того, чтобы просто получать предыдущую строку, вы можете пройти столько строк в "прошлом" или "будущем", сколько захотите.
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
Ответ 4
Основываясь на комментарии @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
или любую другую функцию.
Ответ 5
Следуя решению Аруна, аналогичные результаты могут быть получены без ссылки на .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
Ответ 6
Я добавил аргумент дополнения и изменил некоторые имена и назвал его shift
. https://github.com/geneorama/geneorama/blob/master/R/shift.R
Ответ 7
Вот мое интуитивное решение:
#create data frame
df <- data.frame(A=1:5, B=seq(10,50,10), C=seq(100,500, 100))'
#subtract the shift from num rows
shift <- 1 #in this case the shift is 1
invshift <- nrow(df) - shift
#Now create the new column
df$D <- c(NA, head(df$B, invshift)+tail(df$C, invshift))'
Здесь invshift
, число строк минус 1, равно 4. nrow(df)
предоставляет вам количество строк во фрейме данных или в векторе. Точно так же, если вы хотите принять еще более ранние значения, вычтите из nrow 2, 3,... и т.д., А также положите NA соответственно в начале.
Ответ 8
возможно ли применить функцию сдвига, описанную выше, к отдельным строкам столбца df (в отличие от целого столбца) на основе оператора if/else? Я попытался с приведенным выше кодом в цикле (для (я в 1: nrow (df)).... однако он просто возвращает NA, поэтому я предполагаю, что ему не нравится использование условия строки [i]. Спасибо