Преобразование в местное время в R - Вектор часовых поясов

У меня есть набор данных со всей территории США, которые я пытаюсь преобразовать в местное время для каждого "субъекта". У меня есть метки времени UTC для каждого события, и я преобразовал их в формат POSIXct, но каждый раз, когда я пытаюсь включить вектор tz = DS$Factor или же tz = as.character(DS$Factor) в любой из функций POSIXct/POSIXlt (включая format() а также strftime()) Я получаю сообщение об ошибке:

Ошибка в as.POSIXlt.POSIXct(x, tz = tz): недопустимое значение 'tz'

Если я просто войду tz = 'US/Eastern' он работает нормально, но, конечно, не все мои значения относятся к этому часовому поясу.

Как получить метки времени по местному времени для каждого "предмета"?

DS$Factor имеет 5 значений: США / Аризона США / Центральная часть США / Восточная часть США / Горная часть США / Тихий океан

Спасибо, стенография

3 ответа

Введя dplyr и lubridate, я сделал что-то вроде:

require(lubridate)
require(dplyr)

df = data.frame(timestring = c("2015-12-12 13:34:56", "2015-12-14 16:23:32"),
                localzone = c("America/Los_Angeles", "America/New_York"), stringsAsFactors = F)

df$moment = as.POSIXct(df$timestring, format="%Y-%m-%d %H:%M:%S", tz="UTC")

df = df %>% rowwise() %>% mutate(localtime = force_tz(moment, localzone))

df

На самом деле, я сделал цикл по часовым поясам, а не по количеству строк в наборе данных... тогда это было намного, намного быстрее. Я отправлю код завтра.

В целом, это урок для R: не перебирайте большой фрейм данных, перебирайте (гораздо более короткий) вектор категорий и применяйте с помощью функции which().

Поскольку часовых поясов всего 5, цикл занимает всего несколько секунд.

Еще одно предупреждение: если вы переведете его в формат POSIXct, он все равно будет отображать время в местном часовом поясе вашего компьютера. Так что вам нужен дополнительный шаг, чтобы затем преобразовать его в местное время с помощью force_tz ().

cap $ tdiff на самом деле просто создан, чтобы убедиться, что код делает то, что говорит.

library("lubridate")    

tzs <- as.character(unique(cap$timezone))

cap$localtimes <- as.POSIXlt(0,origin = "1970-01-01")

#now loop through by timezone instead of lines of cap[]
for (i in 1:length(tzs)) {
  whichrows <- which(cap$timezone == tzs[i])

  cap[whichrows,"localtimes"] <-
    with_tz(cap[whichrows,"UTC"],tzone = tzs[i])
}

remove(i, whichrows)

cap$tdiff <- as.numeric((force_tz(cap$localtime, "UTC") - cap$UTC))
cap$localtime <- as.POSIXct(force_tz(cap$localtimes))

Таким образом, я смог создать цикл for, чтобы сделать это, но он медленный и занимает около 10 минут. Я не мог понять apply() sytnax, и, безусловно, был бы признателен за помощь в создании более быстрого, более распараллеливаемого способа выполнения этой операции, поскольку хранилище данных имеет 768 тыс. наблюдений и растет.

>     require(lubridate)
>     
>     loct = NULL for (i in 1:nrow(DS))
>     {
>       loct[i] <- with_tz(DS$UTC[i],tzone =
>       ifelse(DS$timezone[i]=="","US/Eastern",as.character(DS$timezone[i])))
>     } DS$localtime <- as.POSIXct(loct, origin ="1970-01-01") remove (loct, i)
Другие вопросы по тегам