Даты в R
Я работаю над конвейером обработки данных с большим количеством столбцов даты в данных. Многие функции R (например, операции над множествами, sapply
и т. д.) не сохраняйте класс даты, конвертируя даты в целые числа.
Стратегии, которые я вижу, чтобы справиться с этим:
- Убедитесь, что каждая функция в конвейере обработки данных принимает и возвращает даты, отформатированные как даты. Недостаток: выяснить все места, где можно придерживаться
as.Date()
часто утомительно. - Жить с датами как целыми числами на всех этапах обработки, преобразовывая их в даты только в конце. Недостатком является манипулирование датами (например, последовательность с
by = "month"
) на промежуточных этапах жонглирования невозможно без предварительной конвертации в дату.
Любые другие варианты, которые я пропускаю? Есть ли способ заставить R играть хорошо с датами? Для пояснения данные, с которыми я имею дело, - это не просто временной ряд: несколько столбцов содержат даты. Итак, насколько я могу судить, xts
имеет ограниченную полезность.
2 ответа
Не сохраняет Date
Несоответствие классов является артефактом самого R и того, как реализованы некоторые базовые R-функции. См.Например
R> dates <- Sys.Date() + 0:2
R> for (d in dates) cat(d, "\n")
17532
17533
17534
R>
По сути, атрибуты класса S3 удаляются при выполнении определенных векторных операций:
R> as.vector(dates)
[1] 17532 17533 17534
R>
Поэтому я рекомендую выбрать подходящий тип контейнера и придерживаться его для выполнения там операций. Мне очень нравится data.table для этого. Быстрый пример:
R> suppressMessages(library(data.table))
R> dt <- data.table(date=Sys.Date()+0:2, other=Sys.Date() + cumsum(runif(3)*100))
R> dt[, diff:=other-date][]
date other diff
1: 2018-01-01 2018-03-30 88.88445 days
2: 2018-01-02 2018-06-09 158.23913 days
3: 2018-01-03 2018-07-30 208.62187 days
R> dt[, month:=month(other)][]
date other diff month
1: 2018-01-01 2018-03-30 88.88445 days 3
2: 2018-01-02 2018-06-09 158.23913 days 6
3: 2018-01-03 2018-07-30 208.62187 days 7
R>
Мало того, что Date
тип persist (о чем свидетельствует разностная операция, возвращающая difftime
объект), но вы также получаете много вспомогательных функций (например, month()
) Вот. Группировка по дате тоже естественна.
Наверное, нетрудно заменить звонки на sapply
с функцией, которая делает то, что вы хотите. Например,
sapply2 <- function(X, FUN, ...) {
do.call(c, lapply(X, FUN, ...))
}
Это не так универсально, как оригинал sapply
, но если функция, которую вы используете в sapply(X, FUN)
возвращает даты, это сохранит их. Если вы хотите использовать необязательные аргументы для sapply
Вам нужно что-то более сложное.
Я не знаю, сколько других функций есть в вашем "и т. Д.", Но я думаю, что это не очень много, и большинство исправлений не так уж сложно.