4

I have an object that is a multi-level list, where all elements are of class POSIXlt:

[[1]]
 [1] "2015-07-16 GMT" "2015-07-16 GMT" "2015-07-16 GMT" "2015-07-16 GMT" "2015-07-15 GMT"
 [6] "2015-07-15 GMT" "2015-07-15 GMT" "2015-07-15 GMT" "2015-07-15 GMT" "2015-07-14 GMT"
[11] "2015-07-14 GMT" "2015-07-14 GMT" "2015-07-14 GMT" "2015-07-14 GMT" "2015-07-14 GMT"
[16] "2015-07-14 GMT" "2015-07-14 GMT" "2015-07-14 GMT" "2015-07-14 GMT" "2015-07-14 GMT"
[21] "2015-07-13 GMT" "2015-07-13 GMT" "2015-07-13 GMT" "2015-07-13 GMT" "2015-07-13 GMT"
[26] "2015-07-13 GMT" "2015-07-13 GMT" "2015-07-13 GMT" "2015-07-13 GMT"

[[2]]
 [1] "2015-07-12 GMT" "2015-07-11 GMT" "2015-07-11 GMT" "2015-07-11 GMT" "2015-07-11 GMT"
 [6] "2015-07-10 GMT" "2015-07-10 GMT" "2015-07-10 GMT" "2015-07-09 GMT" "2015-07-09 GMT"
[11] "2015-07-09 GMT" "2015-07-09 GMT" "2015-07-09 GMT" "2015-07-09 GMT" "2015-07-09 GMT"
[16] "2015-07-09 GMT" "2015-07-08 GMT" "2015-07-08 GMT" "2015-07-08 GMT" "2015-07-08 GMT"
[21] "2015-07-08 GMT" "2015-07-08 GMT" "2015-07-08 GMT" "2015-07-07 GMT" "2015-07-07 GMT"
[26] "2015-07-07 GMT" "2015-07-07 GMT" "2015-07-07 GMT" "2015-07-06 GMT"

[[3]]
 [1] "2015-07-06 GMT" "2015-07-06 GMT" "2015-07-06 GMT" "2015-07-06 GMT" "2015-07-06 GMT"
 [6] "2015-07-06 GMT" "2015-07-06 GMT" "2015-07-06 GMT" "2015-07-06 GMT" "2015-07-05 GMT"
[11] "2015-07-05 GMT" "2015-07-05 GMT" "2015-07-05 GMT" "2015-07-05 GMT" "2015-07-04 GMT"
[16] "2015-07-04 GMT" "2015-07-04 GMT" "2015-07-04 GMT" "2015-07-03 GMT" "2015-07-03 GMT"
[21] "2015-07-03 GMT" "2015-07-03 GMT" "2015-07-03 GMT" "2015-07-03 GMT" "2015-07-03 GMT"
[26] "2015-07-03 GMT" "2015-07-02 GMT" "2015-07-02 GMT" "2015-07-02 GMT"

When I try to make a single vector with unlist, the object is converted to numeric (i.e. with unlist(dates)). How can I maintain a POSIXlt class?

Example data:

dates <- list(structure(list(sec = c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), min = c(0L, 
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), hour = c(0L, 
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), mday = c(16L, 
16L, 16L, 16L, 15L, 15L, 15L, 15L, 15L, 14L, 14L, 14L, 14L, 14L, 
14L, 14L, 14L, 14L, 14L, 14L, 13L, 13L, 13L, 13L, 13L, 13L, 13L, 
13L, 13L), mon = c(6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 
6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 
6L, 6L), year = c(115L, 115L, 115L, 115L, 115L, 115L, 115L, 115L, 
115L, 115L, 115L, 115L, 115L, 115L, 115L, 115L, 115L, 115L, 115L, 
115L, 115L, 115L, 115L, 115L, 115L, 115L, 115L, 115L, 115L), 
    wday = c(4L, 4L, 4L, 4L, 3L, 3L, 3L, 3L, 3L, 2L, 2L, 2L, 
    2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
    1L, 1L), yday = c(196L, 196L, 196L, 196L, 195L, 195L, 195L, 
    195L, 195L, 194L, 194L, 194L, 194L, 194L, 194L, 194L, 194L, 
    194L, 194L, 194L, 193L, 193L, 193L, 193L, 193L, 193L, 193L, 
    193L, 193L), isdst = c(0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
    0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
    0L, 0L, 0L, 0L, 0L)), .Names = c("sec", "min", "hour", "mday", 
"mon", "year", "wday", "yday", "isdst"), class = c("POSIXlt", 
"POSIXt"), tzone = "GMT"), structure(list(sec = c(0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0), min = c(0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
0L, 0L, 0L), hour = c(0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
0L, 0L, 0L), mday = c(12L, 11L, 11L, 11L, 11L, 10L, 10L, 10L, 
9L, 9L, 9L, 9L, 9L, 9L, 9L, 9L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 7L, 
7L, 7L, 7L, 7L, 6L), mon = c(6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 
6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 
6L, 6L, 6L, 6L, 6L), year = c(115L, 115L, 115L, 115L, 115L, 115L, 
115L, 115L, 115L, 115L, 115L, 115L, 115L, 115L, 115L, 115L, 115L, 
115L, 115L, 115L, 115L, 115L, 115L, 115L, 115L, 115L, 115L, 115L, 
115L), wday = c(0L, 6L, 6L, 6L, 6L, 5L, 5L, 5L, 4L, 4L, 4L, 4L, 
4L, 4L, 4L, 4L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 2L, 2L, 2L, 2L, 2L, 
1L), yday = c(192L, 191L, 191L, 191L, 191L, 190L, 190L, 190L, 
189L, 189L, 189L, 189L, 189L, 189L, 189L, 189L, 188L, 188L, 188L, 
188L, 188L, 188L, 188L, 187L, 187L, 187L, 187L, 187L, 186L), 
    isdst = c(0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
    0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
    0L, 0L)), .Names = c("sec", "min", "hour", "mday", "mon", 
"year", "wday", "yday", "isdst"), class = c("POSIXlt", "POSIXt"
), tzone = "GMT"), structure(list(sec = c(0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
0), min = c(0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L
), hour = c(0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L
), mday = c(6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 5L, 5L, 5L, 5L, 
5L, 4L, 4L, 4L, 4L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 2L, 2L, 2L
), mon = c(6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 
6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L
), year = c(115L, 115L, 115L, 115L, 115L, 115L, 115L, 115L, 115L, 
115L, 115L, 115L, 115L, 115L, 115L, 115L, 115L, 115L, 115L, 115L, 
115L, 115L, 115L, 115L, 115L, 115L, 115L, 115L, 115L), wday = c(1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 0L, 0L, 0L, 0L, 0L, 6L, 6L, 6L, 
6L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 4L, 4L, 4L), yday = c(186L, 
186L, 186L, 186L, 186L, 186L, 186L, 186L, 186L, 185L, 185L, 185L, 
185L, 185L, 184L, 184L, 184L, 184L, 183L, 183L, 183L, 183L, 183L, 
183L, 183L, 183L, 182L, 182L, 182L), isdst = c(0L, 0L, 0L, 0L, 
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L)), .Names = c("sec", "min", 
"hour", "mday", "mon", "year", "wday", "yday", "isdst"), class = c("POSIXlt", 
"POSIXt"), tzone = "GMT"))
Marc in the box
  • 11,769
  • 4
  • 47
  • 97
  • 1
    May be you need to convert it to `POSIXct`, unlist and then reconvert back to `POSIXlt` i..e `tail(as.POSIXlt(unlist(lapply(dates, as.POSIXct)), origin='1970-01-01', tz='GMT'))` – akrun Jul 17 '15 at 08:57
  • Thanks @akrun - looks like you and @Roland both point in the direction of using `POSIXct`. This helps a lot. – Marc in the box Jul 17 '15 at 09:07
  • @Marcinthebox "Class "`POSIXlt`" is a named **list** of vectors" (`?DateTimeClasses`) which is sometimes makes it trickier to handle than `POSIXct`. – Henrik Jul 17 '15 at 09:10

2 Answers2

7

Usually it's far better to use POSIXct. However, if your list is not nested you could use c:

do.call(c, dates)
Roland
  • 127,288
  • 10
  • 191
  • 288
  • 3
    It might be better to put the `c` in double quotes. If the user has a non-function named `c` in the global environment, `do.call(c, dates)` will fail with the error `"Error in do.call(c, list(1:3)) : 'what' must be a character string or a function"`. Clearly it may not be best practice to define `c`, but it's quite common for people to do `a <- 1; b <- 2; c <- 3`. For most purposes, R still works fine in this scenario; `c(1, 2)` will still work, but `do.call(c, x)` won't. Of course if the user has redefined `c` to be a function (e.g. `c <- sum`), then `do.call` will use the redefined function. – Nick Kennedy Jul 17 '15 at 09:24
  • 1
    @NickKennedy I "steal" your comment to answer this https://stackoverflow.com/questions/42499099/do-call-doesnt-like-base-function-c-with-a-list – Alessandro Jacopson Sep 14 '17 at 09:40
5

The POSIXlt objects are themselves lists, and by default unlist will recursively unlist all of the children of the provided object. I thought that using unlist(dates, FALSE) would work, but it doesn't. The options are:

Use do.call and c:

new_dates <- do.call("c", dates)

Go via POSIXct

x <- lapply(dates, as.POSIXct)
y <- unlist(x)
attributes(y) <- attributes(x[[1]])
new_dates <- as.POSIXlt(y)

Note however the need to restore the attributes to y which were lost by unlist.

Nick Kennedy
  • 12,510
  • 2
  • 30
  • 52