Даты в R

Я работаю над конвейером обработки данных с большим количеством столбцов даты в данных. Многие функции R (например, операции над множествами, sapplyи т. д.) не сохраняйте класс даты, конвертируя даты в целые числа.

Стратегии, которые я вижу, чтобы справиться с этим:

  1. Убедитесь, что каждая функция в конвейере обработки данных принимает и возвращает даты, отформатированные как даты. Недостаток: выяснить все места, где можно придерживаться as.Date() часто утомительно.
  2. Жить с датами как целыми числами на всех этапах обработки, преобразовывая их в даты только в конце. Недостатком является манипулирование датами (например, последовательность с 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Вам нужно что-то более сложное.

Я не знаю, сколько других функций есть в вашем "и т. Д.", Но я думаю, что это не очень много, и большинство исправлений не так уж сложно.

Другие вопросы по тегам