我想在data.table中创建一个新列,该列根据一列的当前值和另一列的前一列计算得出。是否可以访问以前的行?
E.g:
> 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
答案 0 :(得分:91)
在v1.9.6中实施shift()
,这非常简单。
DT[ , D := C + shift(B, 1L, type="lag")]
# or equivalently, in this case,
DT[ , D := C + shift(B)]
来自NEWS:
- 新功能
醇>shift()
实现了快速lead/lag
向量,列表, data.frames 或 data.tables 。它需要一个type
参数,可以是“lag”(默认)或“lead”。它可以非常方便地与:=
或set()
一起使用。例如:DT[, (cols) := shift(.SD, 1L), by=id]
。有关详细信息,请查看?shift
。
查看以往答案的历史记录。
答案 1 :(得分:25)
使用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
答案 2 :(得分:19)
有几个人回答了具体问题。请参阅下面的代码,了解我在这种情况下使用的通用功能可能会有所帮助。您可以在&#34;过去&#34;中找到尽可能多的行,而不仅仅是获取前一行。或者&#34;未来&#34;如你所愿。
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
答案 3 :(得分:12)
基于@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
或任何其他功能。
答案 4 :(得分:9)
遵循Arun的解决方案,可以在不参考.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
答案 5 :(得分:1)
我添加了一个填充参数并更改了一些名称并将其命名为shift
。 https://github.com/geneorama/geneorama/blob/master/R/shift.R
答案 6 :(得分:1)
这是我直观的解决方案:
#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相应地放在开头。
答案 7 :(得分:-2)
它可以循环执行。
# Create the column D
DT$D <- 0
# for every row in DT
for (i in 1:length(DT$A)) {
if(i==1) {
#using NA at first line
DT[i,4] <- NA
} else {
#D = C + BPreviousRow
DT[i,4] <- DT[i,3] + DT[(i-1), 2]
}
}
使用for,您甚至可以使用此新列DT[(i-1), 4]
的行的先前值