Why are dates in a list first converted to numeric when coercing to character

Viewed 697

I'm trying to convert a column of dates into strings, because I want to use them as factor levels at some later point in my code.

The date column is part of a tibble, and is of class Date. I figured that a simple as.character() conversion would do the trick, but unfortunately I was wrong. Instead of neatly formatted strings it returns a number in string form. For example today (22 november 2017) would come out as "17492". So somewhere in the process the date gets converted into its numeric format and only then turned into a character string.

Now I did find a workaround, by unlisting the data, converting it again to dates and then to character strings, but it is fairly inefficient.

Can anyone explain i) why this occurs and ii) if there is an easier fix?

Below a reproducible example:

#Get current system date
foo <-Sys.Date()
#Convert to list
foo <- as.list(foo)
#The following then produces the number string:
as.character(foo)
[1] "17492"
#The following code works but is a rather annoying work-around
as.character(as.Date(unlist(foo), origin=as.Date("1970-01-01")))
[1] "2017-11-22"
1 Answers

Given the amount of useful comments and the final solutions provided I'll post an answer summary here.

The first thing to do if you run into this problem is check whether you actually want to convert the full list, or a column within the list, with the column actually being a vector. This was my underlying problem as MrFlick and neilfws pointed out. The reason I missed that was because in my case the list was a one column tibble, the column being named "date". Using as.character(foo) returned my "numeric string" "17492", but using as.character(foo$date), did exactly what it was supposed to do and returned "2017-11-22".

In case your list is really just a list, or a list of lists, the solution of d.b. works like a breeze: use lapply(foo, as.character) or sapply(foo, as.character) depending a bit on your desired output.

Now as to the why this happens: the direct reason, as pointed out by d.b. is that if as.character() encounters a list it first unlist() it, and then does the conversion.

The deeper why was pointed out by joran and the duplicate question on that here. In short: usually it does not make sense to convert a full list to a single data type class, as it can can contain many. For example as.numeric(foo) would just return an error. The only exception to that is as.character(), that actually makes a full write-out of the list (perhaps to keep records).

Related