Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is Date is being returned as type 'double'?

I'm having some trouble working with the as.Date function in R. I have a vector of dates that I'm reading in from a .csv file that are coming in as a factor of integers or as character (depending on how I read in the file, but this doesn't seem to have anything to do with the issue), formatted as %m/%d/%Y.

I'm going through the file row by row, pulling out the date field and trying to convert it for use elsewhere using the following code:

tmpDtm <- as.Date(as.character(tempDF$myDate), "%m/%d/%Y")

This seems to give me what I want, for example, if I do this to a starting value of 12/30/2014, I get the value "2014-12-30" returned. However, if I examine this value using typeof(), R tells me that it its data type is 'double'. Additionally, if I try to bind this to other values and store it in a data frame using c() or cbind(), in the data frame, it winds up being stored as 16434, which looks to me like some sort of different internal storage value of a date. I'm pretty sure that's what it is too because if I try to convert that value again using as.Date(), it throws an error asking for an origin.

So, two questions: Is this as expected? If so, is there a more appropriate way to convert a date so that I actually end up with a date-typed object?

Thank you

like image 814
drRussClay Avatar asked Sep 12 '16 20:09

drRussClay


2 Answers

Dates are internally represented as double, as you can see in the following example:

> typeof(as.Date("09/12/16", "%m/%d/%y"))
[1] "double"

it is still marked a class Date, as in

> class(as.Date("09/12/16", "%m/%d/%y"))
[1] "Date"

and because it is a double, you can do computations with it. But because it is of class Date, these computations lead to Dates:

> as.Date("09/12/16", "%m/%d/%y") + 1
[1] "2016-09-13"
> as.Date("09/12/16", "%m/%d/%y") + 31
[1] "2016-10-13"

EDIT I have asked for c() and cbind(), because they can be assciated with some strange behaviour. See the following example, where switching the order within c changes not the type but the class of the result:

> c(as.Date("09/12/16", "%m/%d/%y"), 1)
[1] "2016-09-12" "1970-01-02"
> c(1, as.Date("09/12/16", "%m/%d/%y"))
[1]     1 17056

> class(c(as.Date("09/12/16", "%m/%d/%y"), 1))
[1] "Date"
> class(c(1, as.Date("09/12/16", "%m/%d/%y")))
[1] "numeric"

EDIT 2 - c() and cbind force objects to be of one type. The first edit shows an anomaly of coercion, but generally, the vector must be of one shared type. cbind shares this behavior because it coerces to matrix, which in turn coerces to a single type.

For more help on typeof and class see this link

like image 78
Bernhard Avatar answered Oct 13 '22 19:10

Bernhard


This is as expected. You used typeof(); you probably should used class():

R> Sys.Date()
[1] "2016-09-12"
R> typeof(Sys.Date())       # this more or less gives you how it is stored
[1] "double"
R> class(Sys.Date())        # where as this gives you _behaviour_
[1] "Date"
R> 

Minor advertisement: I have a new package anytime, currently in incoming at CRAN, which deals with this as it converts "anything" to POSIXct (via anytime()) or Date (via anydate().

E.g.:

R> anydate("12/30/2014")             # no format needed
[1] "2014-12-30"
R> anydate(as.factor("12/30/2014"))  # converts from factor too
[1] "2014-12-30"
R> 
like image 26
Dirk Eddelbuettel Avatar answered Oct 13 '22 20:10

Dirk Eddelbuettel