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 thatifelse()
: thetrue
andfalse
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 thatifelse()
: thetrue
andfalse
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
Difference Between Rbind() and Bind_Rows() in R
Venn Diagram Proportional and Color Shading with Semi-Transparency
Knitr: How to Prevent Text Wrapping in Output
Control the Height in Fluidrow in R Shiny
Insert a Logo in Upper Right Corner of R Markdown PDF Document
How to Use Map from Purrr with Dplyr::Mutate to Create Multiple New Columns Based on Column Pairs
How to Test If List Element Exists
Plot a Function with Ggplot, Equivalent of Curve()
Non-Redundant Version of Expand.Grid
Case-Insensitive Search of a List in R
Analyzing Daily/Weekly Data Using Ts in R
How to Deal with "Data of Class Uneval" Error from Ggplot2
Finding Row Index Containing Maximum Value Using R
Automatically Adjust Latex Table Width to Fit PDF Using Knitr and Rstudio
Using R Statistics Add a Group Sum to Each Row
How to Specify a Dynamic Position for the Start of Substring