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
") astest
and data values from the values ofyes
orno
. The mode of the answer will be coerced from logical to accommodate first any values taken fromyes
and 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.