5

我有一组来自美国各地的数据,我试图将它们转换为每个“主题”的当地时间。我在每个事件上都有 UTC 时间戳并将其转换为 POSIXct 格式,但是每次我尝试在任何 POSIXct/POSIXlt 函数(包括和)中包含向量时tz = DS$Factor,我都会收到一条错误消息:tz = as.character(DS$Factor)format()strftime()

as.POSIXlt.POSIXct(x, tz = tz) 中的错误:“tz”值无效

如果我只是输入tz = 'US/Eastern'它可以正常工作,但当然不是我所有的值都来自那个时区。

如何将每个“主题”的时间戳记为当地时间?

DS$Factor5 个值:US/Arizona US/Central US/Eastern US/Mountain US/Pacific

谢谢,速记

4

3 回答 3

2

引入 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
于 2015-12-15T20:04:45.623 回答
1

实际上,我所做的是遍历时区而不是数据集中的行数......然后它的速度要快得多。我明天会发布代码。

一般来说,这是 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))
于 2015-11-23T23:52:37.803 回答
0

所以我能够创建一个 for 循环来执行此操作,但速度很慢,大约需要 10 分钟才能运行。我想不出一个apply()sytnax,当然会感谢一些帮助,因为数据存储有 768k 的观察值并且还在增长,因此可以创建一种更快、更可并行化的方式来执行此操作。

>     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)
于 2015-08-21T14:31:49.437 回答