r - How to calculate the number of a specific weekday between two POSIXct date arrays and return another numerical array? -
i wrote formula based on weekday calculating algorithm (found in stackexchange well, great job guys. here code snippet:
countwd <- function(start, end, day){ x <- seq(start, end, by=1) y <- weekdays(x, true) sum(y==day) } x$offday <- null for(i in 1:nrow(x)){ x$offday[i] <- countwd(x$pick_date[i], x$ship_date[i], "mon") }
this way slow (loop proceeds 2-4 rows per second!!!!), , have millions of entries each month.
here vectorisation of function:
x$offday <- countwd(x$pick_date, x$ship_date, "mon")
shows error:
error in seq.posixt(start, end, = 1) : 'from' must of length 1
i cannot understand how apply "apply" family functions in case have 2 vectors compare (yes, new this).
sample data:
pick_date ship_date 01-apr-2017 00:51 02-apr-2017 06:55 01-apr-2017 00:51 02-apr-2017 12:11 pm 01-apr-2017 00:51 02-apr-2017 12:11 pm 01-apr-2017 00:51 02-apr-2017 09:39
i have converted these posixct, , formula works individual values (returns second value though, no idea why. however, can work around that):
>countwd(x$pick_date[1], x$ship_date[1], "mon") [1] 0
based on @demirev's answer , comments above, here worked example using improved countwd
function , mapply
. put in few helper columns using lubridate
check solution, , changed of dates return values df$off_days
not zero.
library(lubridate) df <- data.frame(pick_date = c(rep("01-apr-2017 00:51", 4)), ship_date = c("05-apr-2017 06:55", "09-apr-2017 12:11", "30-apr-2017 12:11", "02-may-2017 12:11")) df$pick_date <- lubridate::dmy_hm(df$pick_date) df$ship_date <- lubridate::dmy_hm(df$ship_date) df$pick_day <- wday(df$pick_date, label = t) df$ship_day <- wday(df$ship_date, label = t) df$days_between <- interval(df$pick_date, df$ship_date) %/% days() countwd <- function(start, end, day) { x <- seq(start, end, by="day") y <- weekdays(x, true) sum(y==day) } df$off_days <- mapply(countwd, df$pick_date, df$ship_date, "mon") df pick_date ship_date pick_day ship_day days_between off_days 1 2017-04-01 00:51:00 2017-04-05 06:55:00 sat wed 4 1 2 2017-04-01 00:51:00 2017-04-09 12:11:00 sat sun 8 1 3 2017-04-01 00:51:00 2017-04-30 12:11:00 sat sun 29 4 4 2017-04-01 00:51:00 2017-05-02 12:11:00 sat tues 31 5
Comments
Post a Comment