rdate

Vectorise find closest date function


I would like to pass in a vector of dates, and have returned the closest date from a second vector of (partially matching) dates.

The following function does what I require for a single date, however i cannot figure out how to generalise this to the case where searchDate is a vector of dates.

closestDate <- function(searchDate, dateList, roundDown=FALSE){
  if (roundDown) {
    dist2date <- as.Date(dateList) - as.Date(searchDate)
    closest <- which(max(dist2date[dist2date<=0]) == dist2date)
  } else {
    dist2date <- as.Date(dateList) - as.Date(searchDate)
    closest <- which(min(dist2date[dist2date>=0]) == dist2date)
  }
  return(dateList[closest])
}

dateSeq <- seq(as.Date("2011-01-01"), as.Date("2012-12-19"), by='day')
oddDates <- dateSeq[as.logical(1:length(dateSeq) %%2)]

closestDate('2012-12-14', oddDates)
[1] "2012-12-15"

miscDatesLong <- rep(c('2012-12-14', '2012-12-16', '2012-12-18'), 100 )
closestDate(miscDatesLong, oddDates)

closestDate(miscDatesLong, oddDates)
[1] "2012-12-15" "2012-12-17" "2012-12-19"
Warning message:
In unclass(time1) - unclass(time2) :
  longer object length is not a multiple of shorter object length

Could someone please help?


Solution

  • Now, with the example, just work on the subset of dates that are less than in one case or greater than in the other case, the particular target being examined at the time.

    closestDt <- function(searchDate, dateList, roundDown=FALSE) 
         as.Date( sapply( searchDate , function (x) if( roundDown ){ 
                    max( dateList[ dateList <= x ] ) } else {
                    min( dateList[ dateList >= x])  } 
               ), "1970-01-01")