迭代计算的优化避免了 R 上的循环

optimization of iterative calculation avoiding loops on R

我必须对 R 中 data.frame 的行应用迭代计算。 问题是,对于每一行,结果取决于之前计算的结果和之前的行。

我已经使用类似于以下示例的循环实现了解决方案:

example <- data.frame(flag_new = c(TRUE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,TRUE,FALSE,FALSE,FALSE,FALSE,FALSE,TRUE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE),
                      percentage =sample(1:100,22)/100)
n.Row <- nrow(example)

# initialization
example$K <-0
example$R <-0
example$K[1] <-100
example$R[1] <-example$K[1]*example$percentage[1]

#loop
for(i in 2:n.Row){
  if(example$flag_new[i]){
    example$K[i] <-100

  } else {
    example$K[i] <-example$K[i-1]-example$R[i-1]
  }
  example$R[i] <- example$K[i]*example$percentage[i]
}

问题是实际代码非常慢(特别是如果我在 KNIME 上的 R 代码段中使用它)

有没有办法以更高效的类 R 方式优化代码?我尝试使用 apply 系列,但在我的情况下它似乎不起作用。

非常感谢

这是使用累积 flag_new 分组

data.table 成果
set.seed(1)
example <- data.frame(flag_new = c(TRUE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,TRUE,FALSE,FALSE,FALSE,FALSE,FALSE,TRUE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE),
                      percentage =sample(1:100,22)/100)    

# initialization
initK = 100

# Copy to allow comparison to your code
newd = example

library(data.table)
setDT(newd)[, Knew:= initK* c(1, cumprod(1 - percentage[-.N])), 
                              by=cumsum(flag_new)][, Rnew:=Knew* percentage]

与问题中 运行 循环后的结果进行比较

all.equal(example$K, newd$Knew) 
all.equal(example$R, newd$Rnew)

通过对从第一个 TRUE 到下一个要完成的计算进行分组 计算可以在没有循环的情况下完成。

例如,使用第一组计算可以完成

d = example[1:8, ]
d$K1 <- d$K* c(1, cumprod(1 - d$percentage[-length(d$percentage)]))
d$R2 <- with(d, K1* percentage)

这来自于

k[i] = k[i-1] - R[i-1] 
k[i] = k[i-1] - k[i-1]* p[i-1] 
     = k[i-1](1 - p[i-1])
So 
k[2] = k[1]* (1-p[1])
k[3] = k[2]* (1-p[2]) = k[1]* (1-p[1])* (1-p[2])
k[4] = k[3]* (1-p[3]) = k[1]* (1-p[1])* (1-p[2])* (1-p[3])
and so on..

所以只需要一个拆分、应用、组合方法,为每个组计算这些 为此我使用了 data.table