say I have a date range from start
to end
where start <- as.Date(2009-11-05), end <- as.Date(2009-12-17)
.
I want a function that essentially acts as a customized floor/ceiling and returns a date interval such that the lower bound is the first date of the form 'yyyy-mm-23' smaller or equal to '2009-11-05' and the upper bound is the first date greater or equal to '2009-12-17' and of the form 'yyyy-mm-22'.
In the above example, the function should return the interval ('2009-10-23, 2009-12-22).
I've tried using seq.Date and using the length function on it but it seems tedious and I wonder if there is a faster solution.
Thanks
CodePudding user response:
I don't know a function that works like that, but I would code something like this:
Code
custom_bound <- function(date, type, ref_day){
obs_day <- lubridate::day(date)
if(type == "lower"){aux <- -1}
if(type == "upper"){aux <- 1}
while(obs_day != ref_day ){
date <- date days(aux)
obs_day <- lubridate::day(date)
}
return(date)
}
Output
> custom_bound(date = as.Date("2009-11-05"),type = "lower",ref_day = 23)
[1] "2009-10-23"
> custom_bound(date = as.Date("2009-12-17"),type = "upper",ref_day = 22)
[1] "2009-12-22"
CodePudding user response:
This might be another approach to try. Using lubridate
create new start and end dates, substituting the 23rd and 22nd. Then, if the start date precedes the 23rd, subtract a month. Likewise, if the end date exceeds the 22nd, add a month.
start <- as.Date("2009-11-05")
end <- as.Date("2009-12-17")
library(lubridate)
my_fun <- function(start, end) {
new_start <- start
day(new_start) <- 23
new_end <- end
day(new_end) <- 22
if (day(start) < 23) new_start = new_start %m-% months(1)
if (day(end) > 22) new_end = new_end %m % months(1)
return(interval(new_start, new_end))
}
my_fun(start, end)
Output
[1] 2009-10-23 UTC--2009-12-22 UTC