对R中的逐步模拟进行矢量化

  • 本文关键字:模拟 矢量化 r
  • 更新时间 :
  • 英文 :


我在R中写了一个脚本,在那里我模拟仓库的库存进出:

set.seed(10)
#Create dataframe
df1 <- data.frame(date = seq(1,20),
#Stock in to warehouse on date
stockIn = round(10+10*runif(10),0),
#Stock out of warehouse on date
stockOut = round(10+10*runif(10),0))
#The initial inventory level of the warehouse on date 1
initBalance <- 20
#Create a column of NAs which holds the end of day stock level
df1$endStockBalance <- NA
#Loop through each day
for(i in 1:nrow(df1)){
#If it's the first day, put initBalance into endStockBalance 
if(i == 1){
df1[i,4] <- initBalance
#For other days, take the maximum of the previous day's inventory plus the difference between stock in and stock out, and 0 (we can't have negative stock levels)
} else {
df1[i,4] <- max(df1[i-1,4] + df1[i,2] - df1[i,3],0)
}
}

这适用于for循环,但我想知道是否有一种更优雅的方法来矢量化它,因为这对小列表来说很好,但对较大的列表来说会很慢。

我已经考虑过在dplyr中使用lag,但由于脚本的循序渐进性质,它不起作用。

您基本上可以将循环更改为

cumsum(c(initBalance, df1$stockIn[-1] - df1$stockOut[-1]))
#[1] 20 17 20 21 18 16 18 18 20 16 14 11 14 15 12 10 12 12 14 10

这与我们运行for循环后得到的endStockBalance相同

identical(df1$endStockBalance, 
cumsum(c(initBalance, df1$stockIn[-1] - df1$stockOut[-1])))
#[1] TRUE

如果要为负值指定0,可以使用pmax

pmax(cumsum(c(initBalance, df1$stockIn[-1] - df1$stockOut[-1])), 0)

最新更新