R Ifelse Avoiding Change in Date Format

R ifelse avoiding change in date format

If dat is the dataset. I assume it is is.na(DateOut) from the Travel date column

 as.Date(with(dat, ifelse(is.na(DateOut), DateIn, DateOut)),origin="1970-01-01")
#[1] "2010-11-24" "2012-01-21" "2010-11-25" "2014-01-14"

Or you can do:

 dat$Travel.date <- dat$DateOut
dat$Travel.date[is.na(dat$Travel.date)] <- dat$DateIn[is.na(dat$Travel.date)]
dat
# DateIn DateOut Travel.date
#1 2010-11-24 <NA> 2010-11-24
#2 2011-12-21 2012-01-21 2012-01-21
#3 2010-10-25 2010-11-25 2010-11-25
#4 2014-01-14 <NA> 2014-01-14

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

You may use data.table::fifelse (data.table >= 1.12.3) or dplyr::if_else.



data.table::fifelse

Unlike ifelse, fifelse preserves the type and class of the inputs.

library(data.table)
dates <- fifelse(dates == '2011-01-01', dates - 1, dates)
str(dates)
# Date[1:5], format: "2010-12-31" "2011-01-02" "2011-01-03" "2011-01-04" "2011-01-05"


dplyr::if_else

From dplyr 0.5.0 release notes:

[if_else] have stricter semantics that ifelse(): the true and false arguments must be the same type. This gives a less surprising return type, and preserves S3 vectors like dates" .

library(dplyr)
dates <- if_else(dates == '2011-01-01', dates - 1, dates)
str(dates)
# Date[1:5], format: "2010-12-31" "2011-01-02" "2011-01-03" "2011-01-04" "2011-01-05"

If else statements for dates in R

You don't need SightMonthDay column.

#Function to get season
getSeason <- function(d) {
WS <- as.Date("2016-12-21") # Winter Solstice
SE <- as.Date("2016-3-19") # Spring Equinox
SS <- as.Date("2016-6-20") # Summer Solstice
FE <- as.Date("2016-9-22") # Fall Equinox

ifelse (d >= WS | d < SE, "Winter",
ifelse (d >= SE & d < SS, "Spring",
ifelse (d >= SS & d < FE, "Summer", "Fall")))
}
#Change to standard date format
SampleData$date <- as.Date(SampleData$SightDate, format = '%m/%d/%Y')
#Make date of the same year i.e 2016
SampleData$date <- as.Date(format(SampleData$date, "2016-%m-%d"))
#Get season for each date.
SampleData$SightSeason <- getSeason(SampleData$date)

head(SampleData)
# SightDate date SightSeason
#9977 10/13/2015 2016-10-13 Fall
#11703 6/26/2016 2016-06-26 Summer
#15804 9/15/2017 2016-09-15 Summer
#6177 12/21/2013 2016-12-21 Winter
#12954 12/3/2016 2016-12-03 Fall
#9707 9/18/2015 2016-09-18 Summer

ifelse Statement Returning Number Instead Of Date

See the help file for ifelse

Warning:

The mode of the result may depend on the value of ‘test’ (see the
examples), and the class attribute (see ‘oldClass’) of the result
is taken from ‘test’ and may be inappropriate for the values
selected from ‘yes’ and ‘no’.


Sometimes it is better to use a construction such as

  (tmp <- yes; tmp[!test] <- no[!test]; tmp)

, possibly extended to handle missing values in ‘test’.

This describes precisely what is going on in your example -- the date class attribute is lost -- and a work around -- a multi-step approach.

osa$milldate <- osa$date
ind<- osa$dateloca==TRUE & osa$datelocb==TRUE
osa$milldate[!ind] <- osa$dateminus

Another option is replace.

mutating a new variable with ifelse() loses date format


as.Date(test$NewDOB, origin="1970-1-1")

ifelse on data frame column to replace with date time column values if matched

Package dplyr as a stricter function if_else that verifies the classes of both the true and false components. Explicitly providing the class for the NA value makes this more "type safe"

library(dplyr)
df <- data.frame(txt_col = c("apple", "apple", "orange"),
date_time = as.POSIXct(c("2017-01-01", "2017-01-02", "2017-01-03")))

# use dplyr::if_else instead, and provide explicit class
df$new_col <- if_else(df$txt_col == "apple", df$date_time, as.POSIXct(NA))

df
# txt_col date_time new_col
# 1 apple 2017-01-01 2017-01-01
# 2 apple 2017-01-02 2017-01-02
# 3 orange 2017-01-03 <NA>

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

You may use data.table::fifelse (data.table >= 1.12.3) or dplyr::if_else.



data.table::fifelse

Unlike ifelse, fifelse preserves the type and class of the inputs.

library(data.table)
dates <- fifelse(dates == '2011-01-01', dates - 1, dates)
str(dates)
# Date[1:5], format: "2010-12-31" "2011-01-02" "2011-01-03" "2011-01-04" "2011-01-05"


dplyr::if_else

From dplyr 0.5.0 release notes:

[if_else] have stricter semantics that ifelse(): the true and false arguments must be the same type. This gives a less surprising return type, and preserves S3 vectors like dates" .

library(dplyr)
dates <- if_else(dates == '2011-01-01', dates - 1, dates)
str(dates)
# Date[1:5], format: "2010-12-31" "2011-01-02" "2011-01-03" "2011-01-04" "2011-01-05"


Related Topics



Leave a reply



Submit