How to prevent ifelse() from turning Date objects into numeric objects

后端 未结 6 763
无人及你
无人及你 2020-11-22 04:04

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

6条回答
  •  隐瞒了意图╮
    2020-11-22 04:41

    It relates to the documented Value of ifelse:

    A vector of the same length and attributes (including dimensions and "class") as test and data values from the values of yes or no. The mode of the answer will be coerced from logical to accommodate first any values taken from yes and then any values taken from no.

    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.

提交回复
热议问题