Reputation: 333
i have a data frame of vectors of start dates and end dates:
start_date | end_date | ind |
---|---|---|
2/1/2023 | 2/15/2023 | 0 |
3/4/2023 | 4/17/2023 | 1 |
4/4/2023 | 4/31/2023 | 1 |
new data frame:
start_date | end_date | random_date |
---|---|---|
2/1/2023 | 2/15/2023 | 0 |
3/4/2023 | 4/17/2023 | 3/31/2023 |
4/4/2023 | 4/31/2023 | 4/30/2023 |
I'm looking for generate a random date for a vector for the rows that show an indicator
here is my attempt:
random_date <- as.Date(sample(as.numeric(df$start_date): as.numeric(df$end_date), 1, replace = T), origin = "1970-01-01")
Edited so I can get a time saving solution
Upvotes: 1
Views: 292
Reputation: 52209
With map2_vec
:
library(purrr)
library(dplyr)
df %>%
mutate(random_date = map2_vec(start_date, end_date, \(x, y) sample(seq.Date(x, y, by = "day"), 1)))
# start_date end_date random_date
#1 2023-02-01 2023-02-15 2023-02-01
#2 2023-03-04 2023-04-17 2023-04-08
Note that map2_vec
was introduced in purrr 1.0.0
. It is useful especially in this case, because mapply
or previous purrr::map
functions notoriously failed in returning a date object.
Before purrr 1.0.0
, you can use map
in combination with lubridate::as_date
:
library(lubridate)
df %>%
mutate(random_date = as_date(map2_dbl(start_date, end_date, \(x, y) sample(seq.Date(x, y, by = "day"), 1))))
Upvotes: 0
Reputation: 1303
Here is another solution using seq and sample, as you've done in your provided attempt.
library(dplyr)
df <- data.frame(start_date = c("02/01/2023", "03/04/2023"),
end_date = c("02/15/2023", "04/17/2023"))
df %>%
mutate(start_date = as.Date(start_date, format="%m/%d/%Y"),
end_date = as.Date(end_date, format="%m/%d/%Y")) %>%
rowwise() %>%
mutate(random_date = (seq(start_date, end_date, by="days"))[sample(length(seq(start_date, end_date, by="days")), 1)])
Solution:
start_date end_date random_date
<date> <date> <date>
1 2023-02-01 2023-02-15 2023-02-09
2 2023-03-04 2023-04-17 2023-03-31
Upvotes: 0