Generate random dates in given years

Viewed 150

I have an data set with many columns, one of which is year. For every row, I would like to randomly generate a date, such that it belongs to the year in that row.

library(data.table)
claims <- data.table(claimAmount = runif(n = 10, min = 0, max = 200),
                     claimYear = sample(x = 2014:2019, size = 10, replace = TRUE))

I have that someone posted this function as solution:

    rdate <- function(x,
                      min = paste0(format(claims$claimYear, '%Y'), '-01-01'),
                      max = paste0(format(claims$claimYear, '%Y'), '-12-31'),
                      sort = TRUE) {
      
      dates <- sample(seq(as.Date(min), as.Date(max), by = "day"), x, replace = TRUE)
      if (sort == TRUE) {
        sort(dates)
      } else {
        dates
      }

}

and tried to apply it to by data, but recieved an error of "invalid trim argument":

 apply(claims, 1, rdate)
 Error in prettyNum(.Internal(format(x, trim, digits, nsmall, width, 3L,  : 
  invalid 'trim' argument 

How can I easily generate random dates in R?

3 Answers

Using lubridate::days:

as.POSIXct(paste0(claims$claimYear, "-01-01")) + 
  lubridate::days(sample(0:364, nrow(claims), TRUE))
 [1] "2018-11-15 GMT" "2019-09-02 GMT" "2016-08-02 GMT" "2018-08-02 GMT"   
 [5] "2016-01-09 GMT" "2015-07-05 GMT" "2016-12-19 GMT" "2019-03-04 GMT"  
 [9] "2014-01-06 GMT" "2018-06-17 GMT"

Because your have a data.table, you may create an IDate, sample .N integers, add them, and create the new column by reference.

claims[ , ddate := as.IDate(paste0(claimYear, "-01-01")) + sample(0:364, .N)]

 #    claimAmount claimYear      ddate
 # 1:   76.007036      2018 2018-11-20
 # 2:  155.489044      2015 2015-06-16
 # 3:  186.941046      2015 2015-05-09
 # 4:   42.428504      2019 2019-10-26
 # 5:  130.334753      2014 2014-09-27
 # 6:   25.111019      2017 2017-07-06
 # 7:   53.444134      2014 2014-11-03
 # 8:   77.222819      2017 2017-03-26
 # 9:    2.678067      2016 2016-10-03
 #10:   76.477591      2019 2019-11-26

Since this is tagged data.table:

claims[, rdate := sample(
           seq.Date(
             from = as.Date(paste0(claimYear,"0101"), "%Y%m%d"),
             to = as.Date(paste0(claimYear,"1231"), "%Y%m%d"),
             by = 1
           ), 
          size = 1
        ),
       by = claimYear]

#     claimAmount claimYear      rdate
#  1:   176.47326      2018 2018-01-17
#  2:    18.19580      2015 2015-11-09
#  3:   142.48411      2015 2015-11-09
#  4:    42.76339      2019 2019-08-02
#  5:   177.12420      2014 2014-08-21
#  6:    90.12079      2017 2017-06-07
#  7:   193.57403      2016 2016-02-27
#  8:   107.02539      2019 2019-08-02
#  9:   119.92621      2017 2017-06-07
# 10:   110.95285      2016 2016-02-27
Related