Передача объекта POSIXct в функцию возвращает числовой вектор


Я пытаюсь сделать некоторые манипуляции с вектором POSIXct, но когда я передаю его функции, вектор меняется на вектор numeric, вместо того, чтобы сохранить класс POSIXct, даже если сама функция возвращает только объект:

# Sample dates from vector and it's class.
> dates <- as.POSIXct(c("2012-02-01 12:32:00", "2012-10-24 17:25:56", "2008-09-26 17:13:31", "2011-08-23 11:11:17,", "2015-09-19 22:28:33"), tz = "America/Los_Angeles")
> dates
[1] "2012-02-01 12:32:00 PST" "2012-10-24 17:25:56 PDT" "2008-09-26 17:13:31 PDT" "2011-08-23 11:11:17 PDT" "2015-09-19 22:28:33 PDT"
> class(dates)
[1] "POSIXct" "POSIXt" 
# Simple subset is retaining original class.
> qq <- dates[1:5]
> qq
[1] "2012-02-01 12:32:00 PST" "2012-10-24 17:25:56 PDT" "2008-09-26 17:13:31 PDT" "2011-08-23 11:11:17 PDT" "2015-09-19 22:28:33 PDT"
> class(qq)
[1] "POSIXct" "POSIXt" 
# sapply on the same subset using simple "return" function changes class to "numeric" - why? How to retain "POSIXct"?
> qq2 <- sapply(dates[1:5], function(x) x)
> qq2
[1] 1328128320 1351124756 1222474411 1314123077 1442726913
> class(qq2)
[1] "numeric"

Почему это происходит? Как я могу сохранить класс POSIXct исходного вектора? Я это знаю.POSIXct есть numeric под капотом, но я хочу сохранить исходный класс для удобства чтения.

1 3

1 ответ:

Мы можем использовать lapply вместо sapply, так как sapply по умолчанию имеет опцию simplify = TRUE. Таким образом, если элементы list имеют одинаковую длину, это упростит его до vector или matrix в зависимости от длины элементов list и POSIXct хранится как numeric.

lst <- lapply(dates, function(x) x)

Если нам нужно использовать sapply, то вариант будет simplify = FALSE

lst <- sapply(dates, function(x) x, simplify=FALSE)

После применения функции, если нам нужен в качестве векторного вывода,

do.call("c", lst)

Что касается изменения часового пояса, то оно задокументировано в ?DateTimeClasses

Использование c для объектов POSIXlt преобразует их в текущий часовой пояс, а на объекты "POSIXct" сбрасываются любые атрибуты " tzone "(даже если они все они отмечены одним и тем же часовым поясом).

Таким образом, возможный вариант будет (как указано в комментариях @kmo)

.POSIXct(lst, tz = "America/Los_Angeles")
#[1] "2012-02-01 12:32:00 PST" "2012-10-24 17:25:56 PDT" "2008-09-26 17:13:31 PDT" "2011-08-23 11:11:17 PDT" "2015-09-19 22:28:33 PDT"

Или как @thelatemail упоминается в комментариях

.POSIXct(sapply(dates,I), attr(dates,"tzone") )