Simple dates calculation with foreach

In the code below, you can see that Sys.Date() - months(1) works, but not Sys.Date() - months(i) within a foreach parallel loop. Why won't this work? Is it possible to make it work?

library(tidytable)
#> 
#> Attaching package: 'tidytable'
#> The following object is masked from 'package:stats':
#> 
#>     dt
library(lubridate)
#> 
#> Attaching package: 'lubridate'
#> The following objects are masked from 'package:base':
#> 
#>     date, intersect, setdiff, union
library(foreach)

# Set multi core parallel
cl = parallel::makePSOCKcluster(12)
doParallel::registerDoParallel(cl)

# WORKS
Sys.Date() - months(1)
#> [1] "2022-09-20"

df_output = foreach(i = 1:10,
                    .combine = 'rbind') %dopar% {
                      
                      # DOES NOT WORK
                      date_anything = Sys.Date() - months(i)
                      
                      df = data.frame(abc = i,
                                      def = 123)
                        
                    }
#> Error in {: task 1 failed - "no applicable method for 'months' applied to an object of class "c('integer', 'numeric')""

Created on 2022-10-20 by the reprex package (v2.0.1)

I suspect that Sys.Date() - months(1) will also not work in the foreach loop (, but I did not try it).
Have a look at the documentation for foreach and in particular at the argument .packages.
This may help.

1 Like

The foreach loop when used against the PSOCK cluster and doParallel does not necessarily inherit packages loaded in the main program. In your case It seems like lubridate needs to be present to remap the argument to the months() function.

You will need to explicitly load lubridate in the foreach call via

df_output = foreach(i = 1:10,
                    .combine = 'rbind', .packages=c("lubridate")) %dopar% {

and then the code will no longer error out.

1 Like

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.