我正在尝试解决here提出的问题。基本上,我需要的是,对于data.table的每一行,获取前一行中每个变量的值,并使用它们来定义下一行中的变量值。
我尝试过使用data.table
,但结果相当笨重,而且我认为效率极低(特别是对于大量的行)。我还尝试使用shift()
函数,但无法在我的临时解决方案中使用它。
下面是一个玩具示例:
library(data.table)
DT = data.table(a = numeric(10L), b = numeric(10L), c = numeric(10L), iter = 1:10)
for(i in DT[,.I]){
DT[i, c('a','b','c') := {
if(iter == 1) {
a = 1
b = 2
c = 3
} else { # if it is not the first iteration
a = DT[i-1, a + b] # read the values from the previous row to compute the new values
b = DT[i-1, b] - a
c = a / b + DT[i-1, c]
}
.(a, b, c)
}]
}
下面是输出:
a b c iter
1: 1 2 3.0000000 1
2: 3 -1 0.0000000 2
3: 2 -3 -0.6666667 3
4: -1 -2 -0.1666667 4
5: -3 1 -3.1666667 5
6: -2 3 -3.8333333 6
7: 1 2 -3.3333333 7
8: 3 -1 -6.3333333 8
9: 2 -3 -7.0000000 9
10: -1 -2 -6.5000000 10
有人能帮我改进一下代码吗?
发布于 2019-05-29 07:50:25
另一种选择:
cols <- c('a','b','c')
A <- 1; B <- 2; C <- 3
DT[iter==1, (cols) := .(A, B, C)]
DT[iter>1,
(cols) := {
A = A + B
B = B - A
C = A / B + C
.(A, B, C)
},
by=iter]
发布于 2019-05-28 22:15:08
您可以在acumulate = T
中使用Reduce
fun <- function(x, junk){
x[1] <- sum(x[1:2])
x[2] <- diff(x[1:2])
x[3] <- x[1]/x[2] + x[3]
x
}
dt <-
as.data.table(do.call(rbind, Reduce(fun, numeric(9L), accumulate = T, init = 1:3)))
setnames(dt, c('a', 'b', 'c'))
dt
# a b c
# 1: 1 2 3.0000000
# 2: 3 -1 0.0000000
# 3: 2 -3 -0.6666667
# 4: -1 -2 -0.1666667
# 5: -3 1 -3.1666667
# 6: -2 3 -3.8333333
# 7: 1 2 -3.3333333
# 8: 3 -1 -6.3333333
# 9: 2 -3 -7.0000000
# 10: -1 -2 -6.5000000
您可以使用transpose
而不是do.call(rbind,
,如下所示,但如果加载了tidyverse
或purrr
,请确保transpose
为data.table::transpose
dt <-
as.data.table(transpose(Reduce(fun, numeric(9L), accumulate = T, init = 1:3)))
关于junk
的说明
每次迭代,Reduce
都会将前一个输出(或init
)以及其x
参数的第i个元素传递给f
。因此,即使您不打算在函数f
中使用Reduce
的x
参数,您仍然需要为它提供一个参数。如果你不添加这个额外的“垃圾”参数,你会在运行时得到一个“未使用的参数”错误,因为它试图向f
添加额外的参数,但是f
只有一个参数。
https://stackoverflow.com/questions/56342915
复制相似问题