I am using the function ifelse() to manipulate a date vector. I expected the result to be of class Date, and was surprised to get a numeric>
It relates to the documented Value of ifelse:
A vector of the same length and attributes (including dimensions and "
class") astestand data values from the values ofyesorno. The mode of the answer will be coerced from logical to accommodate first any values taken fromyesand then any values taken fromno.
Boiled down to its implications, ifelse makes factors lose their levels and Dates lose their class and only their mode ("numeric") is restored. Try this instead:
dates[dates == '2011-01-01'] <- dates[dates == '2011-01-01'] - 1
str(dates)
# Date[1:5], format: "2010-12-31" "2011-01-02" "2011-01-03" "2011-01-04" "2011-01-05"
You could create a safe.ifelse:
safe.ifelse <- function(cond, yes, no){ class.y <- class(yes)
X <- ifelse(cond, yes, no)
class(X) <- class.y; return(X)}
safe.ifelse(dates == '2011-01-01', dates - 1, dates)
# [1] "2010-12-31" "2011-01-02" "2011-01-03" "2011-01-04" "2011-01-05"
A later note: I see that Hadley has built an if_else into the the magrittr/dplyr/tidyr complex of data-shaping packages.