Я работаю над проектом, который требует от меня моделирования запасов на большом наборе данных (+20 миллионов строк).
Для этого я сделал следующую функцию:
inventory_calculation <- function(sale, order, dates, expiry_period,
start_inventory, output = c("inv", "waste")) {
sales <- c(sale)
orders <- c(order)
dates <- c(dates)
inv <- c(rep(NA_real_, length(sales)))
waste <- c(rep(NA_real_, length(sales)))
deteriorated <- c()
goods <- c()
goods <- c(goods, rep(dates[1], start_inventory))
remaining_shelf_life <- c()
for( i in seq_along(sales)) {
# Save Current Date
current_date <- dates[i]
if( orders[i] != 0 ) {
# If there are any orders assign products to goods
goods <- c(goods, rep(dates[i], orders[i]))
}
# Calculate duration between current date and replenishment date
remaining_shelf_life <- as.numeric(current_date) - goods
# If any duration is larger than expiry date then remove products from inventory and add to waste bin.
if(any(remaining_shelf_life > expiry_period)) {
deteriorated <- remaining_shelf_life > expiry_period
goods <- goods[deteriorated == F]
waste[i] <- sum(deteriorated == T)
}
# If sales is > 0 then subtract sales from goods
if(sales[i] > 0) {
goods <- goods[-(1:sales[i])]
}
# Save sum of goods in inventory
inv[i] <- ifelse(!is.null(length(goods)), length(goods), 0L)
}
inv <- as.integer(inv)
waste <- as.integer(waste)
if(output == "inv") return(inv) else return(waste)
}
Функция работает нормально, однако она все еще довольно медленная (~ 12 секунд для 700 000 строк).
Поэтому я надеялся, что у некоторых из вас возникнет идея, как сделать это быстрее.
Буду признателен за любую помощь.
Вот некоторые тестовые данные:
library(lubridate)
dates <- seq(dmy("01-01-2018"), dmy("01-09-2018"), "days")
sales <- rpois(length(dates), 10)
orders <- ceiling(rnorm(length(dates), 30, 30))
orders[orders < 0] <- 0L
output <- inventory_calculation(sale = sales,
order = orders,
dates = dates,
expiry_period = 2,
start_inventory = 1,
output = "inv")