R使用以前的迭代值对FOR循环进行矢量化



是否可以矢量化/加速使用先前迭代值的FOR循环的执行?

在下面的繁殖示例中:

  • 当前产量根据当前库存计算
  • 当前生产更新NEXT库存
  • 下一次迭代使用更新后的库存来确定当前产量等

所以我需要在每次迭代时计算库存,以便计算生产设置点。。。有可能避免(慢速(循环吗?

目前50k线路的实施时间约为45秒。

# Dummy functions for the examples. Real code is more complicated
function1 <- function(energy, stock, critical) {
if (stock < critical) {
return (energy)
} else {
return(0)
}
}
function2 <- function(power) {
return(round(power/100))
}
# Dummy data
d <- data.frame( "energy"= c(660, 660, 660, 660),
"stock" = c(20,   0,    0, 0),
"delivery" = c(0, 0, 2, 0),
"critical" = c(50, 50 ,50, 50),
"power" = c(0, 0, 0, 0),
"production" = c(0, 0, 0, 0) )
for (i in 1:length(d$energy)) {
# Computing power, based on CUURENT stock
d$power[i] <- function1(d$energy[i], d$stock[i], d$critical[i])
# Computing production
d$production[i] <- function2(d$power[i])
# Updating NEXT stock with current production / delivery
if (i < length(d$energy)) {
d$stock[i+1] <- d$stock[i] + d$production[i] - d$delivery[i]
}
}
View(d)

基础中,您可以将Reduceaccumulate = TRUE一起使用,如:

fun  <- function(x,y) {
ttStock <- x[[2]] + x[[6]] - x[[3]]
ttPower <- function1(y[[1]], ttStock, y[[4]])
ttProduction <- function2(ttPower)
c(y[[1]], ttStock, y[[3]], y[[4]], ttPower, ttProduction)
}
d$power[1] <- function1(d$energy[1], d$stock[1], d$critical[1])
d$production[1] <- function2(d$power[1])
do.call(rbind, Reduce(fun, as.data.frame(t(d[-1,])), d[1,], accumulate = TRUE))
#  energy stock delivery critical power production
#1    660    20        0       50   660          7
#2    660    27        0       50   660          7
#3    660    34        0       50   660          7
#4    660    39        2       50   660          7

为了更容易,我在d的第一行中填写了powerproduction

如果您使用名称而不是列号:

fun  <- function(x,y) {
names(x)  <- colnames(d)
ttStock <- x[["stock"]] + x[["production"]] - x[["delivery"]]
ttPower <- function1(y[[1]], ttStock, y[[4]])
ttProduction <- function2(ttPower)
c(y[[1]], ttStock, y[[3]], y[[4]], ttPower, ttProduction)
}

一种可能性是使用dplyr包,它是tidyverse的一部分。

library(dplyr)
d %>%
mutate(power = function1(energy, stock, critical),
production = function2(power),
stock_new = cumsum(stock + lag(production - delivery, 1, default = 0)))
energy stock delivery critical power production stock_new
1    660    20        0       10   500          5        20
2    660     0        0       10   500          5        25
3    660     0        2       10   500          5        30
4    660     0        0       10   500          5        33

如果函数CCD_ 8和CCD_。如果没有,则必须在mutate中使用purrr::map

如何在函数调用之间保存状态。

my_env <- new.env(parent = emptyenv())
my_env$stock <- d$stock[0]
f <- function(item){
power <- function1()
production <- function1()/100
stock <- my_env$stock 
....
rest of the businesss logic
...
}
apply(d, 2, f)

最新更新