jkabrg jkabrg - 9 months ago 40
R Question

Why is POSIXct converted to numeric when converting list to vector

I have a list

is a class with a field
. I am trying to form a list of times in which tweets were posted. Here is how I'm trying to do it

times <- unlist(lapply(redDressTweets, function(tweet) {tweet$created }))

The output is a vector of numbers:

[1] 1478044029 1477954062 1477909847 1477887746 1477832560 1477640940 1477640939
[8] 1477628031 1477540826

But the class of

Why is this happening and how do I stop it from converting POSIXct to numeric?


Why was this downvoted?

Answer Source

You can reproduce more easily like this:

x <- list(as.POSIXct("2016-11-02"), as.POSIXct("2016-11-03"))
#[1] 1478041200 1478127600

unlist combines the values inside the list. The internal representation of POSIXct variables are numeric values. They only are a POSIXct variable due to attributes, most importantly the class attribute. A list can hold all kinds of objects. The documentation says:

Where possible the list elements are coerced to a common mode during the unlisting, and so the result often ends up as a character vector. Vectors will be coerced to the highest type of the components in the hierarchy NULL < raw < logical < integer < double < complex < character < list < expression: pairlists are treated as lists.

Note that it says "common mode", not common class. Since a class could be anything and could enforce any kind of underlying structure (e.g., it might not even be possible to combine two objects of the same class in a meaningful way), unlist just strips all attributes (except for a list where all elements are factors). It would be possible to handle POSIXct values like factor values, but that's not the case (and might have performance implications).

You can't avoid this, but fix it easily:

y <- unlist(x)
attributes(y) <- attributes(x[[1]])
#[1] "2016-11-02 CET" "2016-11-03 CET"

Obviously this assumes that all list elements have the same timezone attribute.