参考R中data.table中的上一行,带有条件
我对这些数据有一个新的问题。因为我的全部数据都是这样的参考R中data.table中的上一行,带有条件,r,data.table,R,Data.table,我对这些数据有一个新的问题。因为我的全部数据都是这样的 a=data.table(A=c(1:10),B=c(1,2,0,2,0,0,3,4,0,2),C=c(2,3,1,4,5,3,6,7,2,2),D=c(1,1,1,1,1,2,2,2,2,2)) # A B C D # 1: 1 1 2 1 # 2: 2 2 3 1 # 3: 3 0 1 1 # 4: 4 2 4 1 # 5: 5 0 5 1 # 6: 6 0 3 2 # 7: 7
a=data.table(A=c(1:10),B=c(1,2,0,2,0,0,3,4,0,2),C=c(2,3,1,4,5,3,6,7,2,2),D=c(1,1,1,1,1,2,2,2,2,2))
# A B C D
# 1: 1 1 2 1
# 2: 2 2 3 1
# 3: 3 0 1 1
# 4: 4 2 4 1
# 5: 5 0 5 1
# 6: 6 0 3 2
# 7: 7 3 6 2
# 8: 8 4 7 2
# 9: 9 0 2 2
#10: 10 2 2 2
现在,我想创建一个新列,只要B不是0,它就可以计算上一行B/C的倍数。例如,在第2行中,我可以计算D=2*(1/2)。但是,在第4行中,它必须是4*(2/3),不能是4*(0/1)。
我用
有人知道这里有什么问题吗?错误是较长的对象长度不是较短对象长度的倍数。我们可以将“B”、“C”中与“B”中的“0”值对应的元素替换为NA。使用
zoo
中的na.locf
将这些na值替换为以前的非na元素,shift
元素(默认情况下,它给出的lag
为1),将修改后的列“B”除以“C”,然后乘以“a”。将(:=
)输出分配给新列“D”
library(zoo)
a[B==0, c('B', 'C'):=list(NA, NA)]
a[, c('B', 'C'):= na.locf(.SD), .SDcols=B:C]
a[, D:= {tmp <- shift(.SD[, 2:3, with=FALSE])
A*(tmp[[1]]/tmp[[2]])}]
或者不调用两次shift/na.locf
a[, D:= {i1 <- (NA^!B)
tmp <- shift(na.locf(i1*.SD))
a[['A']]*(tmp[[1]]/tmp[[2]])}, .SDcols=B:C]
a[,D:={i1这可以通过滚动连接完成:
a[, row := .I]
a[, B/C, by=row][V1 != 0][a, A*shift(V1), on="row", roll=TRUE]
# [1] NA 1.000000 2.000000 2.666667 2.500000 3.000000 3.500000 4.000000
# [9] 5.142857 5.714286
D的第一个元素的输出是什么?D的第一个元素的输出是NAThanks。你真的解决了我的问题。它也很紧凑。嗨,@akrun,你能看一下吗?@ThanhQuang你可能需要…na.locf(i1*B),na.rm=FALSE)/shift(na.locf(i1*C,na.rm=FALSE)…
谢谢。现在一切都解决了。非常感谢您
a[, D:= {i1 <- (NA^!B)
list( A*shift(na.locf(i1*B))/shift(na.locf(i1*C)))}]
a[, D:= {i1 <- (NA^!B)
tmp <- shift(na.locf(i1*.SD))
a[['A']]*(tmp[[1]]/tmp[[2]])}, .SDcols=B:C]
a[, row := .I]
a[, B/C, by=row][V1 != 0][a, A*shift(V1), on="row", roll=TRUE]
# [1] NA 1.000000 2.000000 2.666667 2.500000 3.000000 3.500000 4.000000
# [9] 5.142857 5.714286