4

I am experiencing an issue working with POSIXct objects. With using functions that return POSIXct objects with sapply(), sapply() seems to automatically convert them to numeric.

lapply() seems to maintain the POSIXct class, but when I unlist(), I lose it again.

Is there a way to take advantage of apply() while still using POSIXct? I have a project at work with lots of date-time information, and I'm getting frustrated. Many thanks!

# unwanted POSIXct conversion to numeric
as.POSIXct(Sys.time(), "GMT") %>% rep(5) %>% sapply(function(x) x) 

# lapply seems to maintain POSIXct class, but if I unlist(), I lose POSIXct again
as.POSIXct(Sys.time(), "GMT") %>% rep(5) %>% lapply(function(x) x) 
as.POSIXct(Sys.time(), "GMT") %>% rep(5) %>% lapply(function(x) x) %>% unlist()
Arthur
  • 1,248
  • 8
  • 14
  • I guess I would first check to make sure you aren't missing ways to operate on POSIXct vectors with vectorization, rather than with *apply(), next I'd have to resort to `do.call("c",myListOfPOSIXct)`. – joran Mar 22 '19 at 17:04
  • I think the problem is that `apply` a conversion to `matrix`. Passing a `POSIXct` object to `matrix` or `as.matrix` has the same effect. – divibisan Mar 22 '19 at 17:06
  • ^ This seems to be the same issue. Replacing `unlist` with `do.call(c, .)` produces the desired result – divibisan Mar 22 '19 at 17:08
  • Add `as.POSIXct(origin = ...)` this to the end of either lapply or sapply: `%>% as.POSIXct(origin = "1970-01-01 00:00 AM")` – shwan Mar 22 '19 at 17:12
  • 1
    You can also do `class(x) <- c("POSIXct", "POSIXt")`. It's not clear what a real example function would look like here. Many datetime operations are vectorizable like `Sys.time() + 1` (still a POSIXct) – Frank Mar 22 '19 at 17:12
  • 1
    I think the real WTF (and the underlying reason) is why `unlist` doesn’t preserve the class, *but only* if the input is a list. This isn’t specific to `sapply`, nor to `POSIXct`. What’s more, since this is clearly an absolute core behaviour of the language in combination with S3, I’m puzzled I haven’t encountered this before. The duplicate neither explains nor solves this general case. – Konrad Rudolph Mar 22 '19 at 17:15

1 Answers1

-1

I'm not sure it is the most efficient way but as a quick fix you could convert them to character first

as.POSIXct(sapply(rep(as.POSIXct(Sys.time(), "GMT"),5), function(x) as.character(x)))

## [1] "2019-03-22 19:24:37 CET" "2019-03-22 19:24:37 CET"
## [3] "2019-03-22 19:24:37 CET" "2019-03-22 19:24:37 CET"
## [5] "2019-03-22 19:24:37 CET"

Update

That leaves the question why do you need sapply in the first place?

 as.POSIXct(rep(Sys.time(),5))


##[1] "2019-03-22 19:29:40 CET" "2019-03-22 19:29:40 CET"
##[3] "2019-03-22 19:29:40 CET" "2019-03-22 19:29:40 CET"
##[5] "2019-03-22 19:29:40 CET"
DJJ
  • 2,481
  • 2
  • 28
  • 53
  • 1
    This was just an [mcve]. They want to apply some function to a vector of `POSIXct` objects without losing their class – divibisan Mar 22 '19 at 17:16
  • Granted that it might lead to more general questions. But is was not stated in this way. I quote. Is there a way to take advantage of apply() while still using POSIXct? I have a project at work with lots of date-time information, and I'm getting frustrated. Many thanks!. – DJJ Mar 22 '19 at 17:28