Reputation: 342
I am doing a date comparison in R and the output class is awkward, as I was expecting a date object, but I am receiving a numeric. Can you explain why? What is the logic behind it?
library(data.table)
library(lubridate)
dt <- data.table(date_hist = ymd(seq.Date(as.Date("2018-01-01"), by = "month", length.out = 24)))
dt[,date_aux := ifelse(date_hist>max(date_hist),ymd(as.Date(max(date_hist),format = "%Y-%m-%d")),ymd(as.Date(date_hist,format = "%Y-%m-%d")))]
date_hist date_aux
1: 2018-01-01 17532
2: 2018-02-01 17563
3: 2018-03-01 17591
4: 2018-04-01 17622
5: 2018-05-01 17652
6: 2018-06-01 17683
7: 2018-07-01 17713
8: 2018-08-01 17744
9: 2018-09-01 17775
10: 2018-10-01 17805
11: 2018-11-01 17836
12: 2018-12-01 17866
13: 2019-01-01 17897
14: 2019-02-01 17928
15: 2019-03-01 17956
16: 2019-04-01 17987
17: 2019-05-01 18017
18: 2019-06-01 18048
19: 2019-07-01 18078
20: 2019-08-01 18109
21: 2019-09-01 18140
22: 2019-10-01 18170
23: 2019-11-01 18201
24: 2019-12-01 18231
date_hist date_aux
sapply(dt,class)
date_hist date_aux
"Date" "numeric"
Upvotes: 1
Views: 550
Reputation: 887108
Instead of ifelse
use fifelse
library(data.table)
dt[, date_aux := fifelse(date_hist>max(date_hist),ymd(as.Date(max(date_hist),
format = "%Y-%m-%d")),ymd(as.Date(date_hist,format = "%Y-%m-%d")))]
str(dt)
#Classes ‘data.table’ and 'data.frame': 24 obs. of 2 variables:
# $ date_hist: Date, format: "2018-01-01" "2018-02-01" "2018-03-01" "2018-04-01" ...
# $ date_aux : Date, format: "2018-01-01" "2018-02-01" "2018-03-01" "2018-04-01" ...
with ifelse
, the dates are converted to its storage mode i.e. numeric
If we check the source code, it is at the last few lines of assignment that creates the issue
...
ans <- test
len <- length(ans)
ypos <- which(test)
npos <- which(!test)
if (length(ypos) > 0L)
ans[ypos] <- rep(yes, length.out = len)[ypos]
if (length(npos) > 0L)
ans[npos] <- rep(no, length.out = len)[npos]
ans
...
With a simple example
v1 <- Sys.Date() - 1:5
v2 <- Sys.Date() + 1:5
ans <- v1 > Sys.Date() - 2 # logical vector
ypos <- which(ans)
npos <- which(!ans)
ans[ypos] <- rep(v2, length.out = length(ans))[ypos] Datess
ans
#[1] 18335 0 0 0 0
assigning Date
class on the logical vector coerces the Date to convert to numeric
Upvotes: 3