Векторизация пошагового моделирования в R - PullRequest
0 голосов
/ 07 декабря 2018

Я написал скрипт на 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, но я хочу знать, есть либолее элегантный подход с помощью векторизации, так как это хорошо для небольших списков, но это будет довольно медленно для большего числа.

Я смотрел на использование lag в dplyr, но из-запошаговый характер скрипта, который не работает.

1 Ответ

0 голосов
/ 07 декабря 2018

Вы можете в основном изменить цикл на

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

, который совпадает с вашим endStockBalance, который мы получаем после запуска for loop

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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...