Преобразование в местное время в 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)