Why are my functions on lubridate dates so slow?

date, lubridate, r

Solution

You're looping over every single row. It's not surprising it is slow. You could essentially do one replacement operation instead where you take a fixed difference from each date: 0 for M-F, -1 for Sat and -2 for Sun.

# 'big' sample data
x <- Sys.Date() + 0:100000

bizdays <- function(x) x - match(weekdays(x), c("Saturday","Sunday"), nomatch=0)

# since `weekdays()` is locale-specific, you could also be defensive and do:
bizdays <- function(x) x - match(format(x, "%w"), c("6","0"), nomatch=0)

system.time(bizdays(x))
#   user  system elapsed 
#   0.36    0.00    0.35 

system.time(previous_business_date_if_weekend(x))
#   user  system elapsed 
#  45.45    0.00   45.57 

identical(bizdays(x), previous_business_date_if_weekend(x))
#[1] TRUE

Problem

I wrote this function which I use all the time: ``` # Give the previous day, or Friday if the previous day is Saturday or Sunday. previous_business_date_if_weekend = function(my_date) { if (length(my_date) == 1) { if (weekdays(my_date) == "Sunday") { my_date = lubridate::as_date(my_date) - 2 } if (weekdays(my_date) == "Saturday") { my_date = lubridate::as_date(my_date) - 1 } return(lubridate::as_date(my_date)) } else if (length(my_date) > 1) { my_date = lubridate::as_date(sapply(my_date, previous_business_date_if_weekend)) return(my_date) } } ``` Problems arise when I apply it to a date column of a dataframe with thousands of rows. It's ridiculously slow. Any thoughts as to why?

Original source

Related problems