Comparing two date vectors with a function in R to avoid a loop and deal with NA

There is probably a very trivial workaround for this, but it goes ... I'm trying to compare two date vectors in R (not initially entered as vectors): return the first value if the second is NA, but not enough at first; return the largest of the two dates if the second has not disappeared; or return NA if both values ​​are missing. For example, for the data presented below, I would like lastdate calculate the following:

 v1 v2 lastdate 1/2/2006 NA 1/2/2006 1/2/2006 12/2/2006 12/2/2006 NA NA NA 

I wrote a formula to avoid looping over each row (85K in this data) as follows:

 lastdate <- function(lastdate1,lastdate2){ if (is.na(lastdate1)==T & is.na(lastdate2)==T) {NA} else if (is.na(lastdate2)==T & !is.na(lastdate1)) {as.Date(lastdate1,format="%m/%d/%Y")} else {max(as.Date(lastdate2,format="%m/%d/%Y"),as.Date(lastdate1,format="%m/%d/%Y"))} } dfbobs$leaveobsdate <- lastdate(as.Date(dfbobs$leavedate1,format="%m/%d/%Y"),as.Date(dfbobs$leavedate2,format="%m/%d/%Y")) 

The last line tells him to compare two date vectors, but is not quite right, as I get errors

 Warning messages: 1: In if (is.na(lastdate1) == T & is.na(lastdate2) == T) { : the condition has length > 1 and only the first element will be used 2: In if (is.na(lastdate2) == T & !is.na(lastdate1)) { : the condition has length > 1 and only the first element will be used 

I'm sure this is very stupid, and probably a much simpler way to do this, but any help would be appreciated.

EDIT: now I tried to use the ifelse function to process vectors, as suggested, but the comparison, when working, if I type single values ​​(for example, lastdate ("1/1/2006", "1/2/2006")) creates NA if I try to use it in data vectors. Code follows:

 lastdate <- function(lastdate1,lastdate2){ ifelse(is.na(lastdate1==T) & is.na(lastdate2==T), NA, ifelse(is.na(lastdate2)==T & !is.na(lastdate1), as.Date(lastdate1,format="%m/%d/%Y"), ifelse(!is.na(lastdate2) & !is.na(lastdate1), max(as.Date(lastdate2,format="%m/%d/%Y"),as.Date(lastdate1,format="%m/%d/%Y")),NA))) } dfbobs$leaveobsdate <- as.Date(lastdate(as.Date(dfbobs$leavedate1,format="%m/%d/%Y"),as.Date(dfbobs$leavedate2,format="%m/%d/%Y")),origin="1970-01-01") 
+4
source share
2 answers

try the following:

convert dates to digital as follows

 v1<-as.character(v1); v2<-as.character(v2); v1<-as.numeric(strftime(strptime(v1,"%m/%d/%Y"),"%Y%m%d")); v2<-as.numeric(strftime(strptime(v2,"%m/%d/%Y"),"%Y%m%d")); 

calculate the result now

 result<-ifelse(!is.na(v1) | !is.na(v2),max(v1,v2,na.rm=TRUE),NA); 

return to the format of your choice

 result<-strptime(result,"%Y%m%d"); result<-strftime(result,"%m/%d/%Y"); 
+1
source

if not vectorized - it expects one argument. Use ifelse .

Alternatively, you can use mapply with your existing function:

 mapply(lastdate, as.Date(df$leavedate1, ...), as.Date(df$v2, ...)) 
+1
source

All Articles