Подтвердить что ты не робот

Лить строку непосредственно в IDateTime

Я использую новую версию data.table и особенно функцию AWESOME fread. Мои файлы содержат даты, которые загружаются как строки (потому что я не знаю, чтобы сделать это иначе), как 01APR2008:09:00:00.

Мне нужно отсортировать таблицу data.table в те моменты времени, а затем для сортировки, чтобы быть эффективными для того, чтобы отдать затем в формате IDateTime (или что-нибудь еще, чего я еще не знаю).

> strptime("01APR2008:09:00:00","%d%b%Y:%H:%M:%S")
[1] "2008-04-01 09:00:00"

> IDateTime(strptime("01APR2008:09:00:00","%d%b%Y:%H:%M:%S"))
        idate    itime
1: 2008-04-01 09:00:00

> IDateTime("01APR2008:09:00:00","%d%b%Y:%H:%M:%S")
Error in charToDate(x) : 
character string is not in a standard unambiguous format 

Похоже, я не могу сделать DT[ , newType := IDateTime(strptime(oldType, "%d%b%Y:%H:%M:%S"))].

Мои вопросы:

  • Есть ли способ прямого перевода на IDateTime из fread, чтобы я мог сортировать впоследствии эффективно?
  • Если нет, то какой самый эффективный способ узнать, что я хотел бы сортировать DT по этому столбцу datetime.
4b9b3361

Ответ 1

К сожалению (для эффективности) strptime создает тип POSIXlt, который не поддерживается data.table и всегда будет зависеть от его размера (40 байт за дату!) и структуры. Хотя strftime создает намного лучший POSIXct, он все еще делает это через POSIXlt. Подробнее здесь:

http://stackoverflow.com/a/12788992/403310

Глядя на базовые функции, такие как as.Date, он также использует strptime, создавая целочисленное смещение от эпохи (как-то), хранящейся как double. Класс IDate (и друзей) в data.table направлен на достижение целочисленных смещений эпохи, сохраненных как, um, integer. Подходит для быстрой сортировки base::sort.list(method = "radix") (что действительно является сортировкой). IDate на самом деле не нацелен на быстрое (обычно однократное) преобразование.

Итак, чтобы преобразовать строковые даты/времена, правильно или неправильно, я склонен сворачивать свою собственную вспомогательную функцию.

Если строковая дата "2012-12-24", я наклоняюсь к: as.integer(gsub("-", "", col)) и продолжаю с целыми датами YYYYMMDD. Точно так же время может быть HHMMDD как целое число. Два столбца: date и time отдельно могут быть полезны, если вы обычно хотите roll = TRUE в течение дня, но не до предыдущего дня. Группировка по месяцам проста и быстра: by = date %/% 100L. Добавление и вычитание дней затруднительно, но это так или иначе, потому что редко вы хотите добавить календарные дни, а не будние дни или рабочие дни. Так что в любом случае поиск в векторе рабочего дня.

В вашем случае для месяца символа потребуется преобразование в 1:12. В ваших датах "01APR2008" нет разделителя, поэтому substring будет одним из способов, за которым следует match или fmatch в имени месяца. Вы контролируете формат файла? Если это так, цифры лучше в однозначном формате, который выглядит естественно, например %Y-%m-%d или %Y%m%d.

Я еще не понял, как лучше всего это сделать в fread, поэтому date/times остаются в качестве символа в настоящее время, потому что я еще не уверен, как определить формат даты или тип для вывода. Для этого нужно вывести либо целые, либо двойные даты, а не неэффективный характер. Я подозреваю, что использование целых чисел YYYYMMDD рассматривается как нетрадиционное, поэтому я немного не решаюсь сделать это по умолчанию. У них есть свое место, и есть плюсы и минусы эпохальных дат. Даты не всегда должны быть основаны на эпохе - это все, что я предлагаю.

Как вы думаете? Кстати, спасибо за поддержку fread; было приятно видеть.

Ответ 2

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

Здесь я использую зоопарк для этого. (Здесь я полагаю, что столбец даты является первым, иначе см. аргумент index.colum)

ff <- function(x) as.POSIXct(strptime(x,"%d%b%Y:%H:%M:%S"))

h <- read.zoo(text = "03avril2008:09:00:00  125
                      02avril2008:09:30:00  126
                      05avril2008:09:10:00  127
                      04avril2008:09:20:00  128
                      01avril2008:09:00:00  128"
                      ,FUN=ff)

Ваши даты отсортированы в нужном формате и отсортированы.

Преобразование является естественным с POSIXct на IDateTime

    IDateTime(index(h))
        idate    itime
1: 2008-04-01 09:00:00
2: 2008-04-02 09:30:00
3: 2008-04-03 09:00:00
4: 2008-04-04 09:20:00
5: 2008-04-05 09:10:00

Здесь уверен, что вы все еще делаете 2 конверсии, но делаете это при чтении данных, а во втором - без проблем с форматом.