Jesster Jesster - 3 days ago 5
R Question

function for accurate end date based on specified interval

I'm working on a function to create a 2-column df containing StartDate & EndDate. I'll supply 3 parameters: startdate, enddate, & interval, where interval indicates whether each row should represent different days, months or years within the range I provide.

For example, this:

myfunction("2016/01/01", "2016/04/30", "months")


would generate the same thing as this:

sd <- c("2016/01/01","2016/02/01","2016/03/01","2016/04/01")
ed <- c("2016/01/31","2016/02/29","2016/03/31","2016/04/30")
df <- data.frame(sd, ed)


And this:

myfunction("2016/01/01","2016/01/05", "days")


would generate the same thing as this:

sd <- c("2016/01/01","2016/01/02","2016/01/03","2016/01/04","2016/01/05")
ed <- c("2016/01/01","2016/01/02","2016/01/03","2016/01/04","2016/01/05")
df <- data.frame(sd, ed)


Here's what I've tried so far:

range <- function(startdate, enddate, interval){
sd <- seq(as.Date(startdate), as.Date(enddate), interval)
ed <- seq(as.Date(startdate), as.Date(enddate), interval) -1
df <- data.frame(sd,ed)
return(View(df))
}


But whether I run the function for days or months, the end date is wrong. See:

range("2016/01/01","2016/01/05","days")

range("2016/01/01","2016/04/30","months")


How can I code so that my function consistently returns the correct end date, regardless of whether I'm looking at days, months, or years? I've reviewed other questions here but they all seem to use static intervals rather than dynamic.

Answer
library(lubridate)

# Start date and end date should be of character type
# interval should be "day" or "month" or "year"

get_range <- function(start, end, interval)
 {
  col1 <- seq(from = as.Date(start, format = "%m/%d/%Y"),
                         to = as.Date(end, format = "%m/%d/%Y"),
                         by = interval)
  col2 <- col1 + sapply(col1, function(x){ifelse(interval == "day", days(1),
                    ifelse(interval == "month", 
                           days_in_month(month(x)) - day(x),
                           365))})
  return(data.frame(col1,col2))
 }
Comments