with_tz与时区矢量

jos*_*kre 6 r lubridate dplyr

我有一个像这样的数据帧:

library(dplyr)
data <- data_frame(
  timestamp_utc = c('2015-11-18 03:55:04', '2015-11-18 03:55:08', 
                    '2015-11-18 03:55:10'),
  local_tz = c('America/New_York', 'America/Los_Angeles', 
               'America/Indiana/Indianapolis')
  )
Run Code Online (Sandbox Code Playgroud)

我需要创建一个新的变量,将UTC时间戳转换为local_tz列中定义的本地时间.然而,两者formatwith_tz(来自lubridate)只期望一个时区,而不是时区矢量.我正在寻找这样的东西:

mutate(data, timestamp_local = with_tz(timestamp_utc, tzone = local_tz))
Run Code Online (Sandbox Code Playgroud)

有任何想法吗?

jer*_*ycg 6

首先确保您的数据作为日期加载 - 我必须先转换为日期:

data$timestamp_utc <- as.POSIXct(data$timestamp_utc, tz = "UTC")
Run Code Online (Sandbox Code Playgroud)

然后你可以使用rowwisefrom函数dplyr,结合使用do

library(lubridate)
library(dplyr)
z <- data %>% rowwise() %>%
              do(timestamp_local = with_tz(.$timestamp_utc, tzone = .$local_tz))
data$timestamp_local <- z$timestamp_local

data$timestamp_local
[[1]]
[1] "2015-11-17 22:55:04 EST"

[[2]]
[1] "2015-11-17 19:55:08 PST"

[[3]]
[1] "2015-11-17 22:55:10 EST"
Run Code Online (Sandbox Code Playgroud)

我们需要将 timestamp_local 列设为一个列表,否则所有时区都将转换回一个向量中只能有一个时区)。


jos*_*kre 3

这是一种方法。这样,结果必须是字符串,否则unlist()c()会将列表中每个元素的结果返回到系统时区。

但它仍然很慢,因为它没有矢量化。

> get_local_time <- function(timestamp_utc, local_tz) {
    l <- lapply(seq(length(timestamp_utc)), 
                function(x) {format(with_tz(timestamp_utc[x], local_tz[x]), "%FT%T%z")})
    unlist(l)
    }

> mutate(data, timestamp_local = get_local_time(timestamp_utc, tzone = local_tz))

Source: local data frame [3 x 3]

        timestamp_utc                     local_tz          timestamp_local
               (time)                        (chr)                    (chr)
1 2015-11-18 03:55:04             America/New_York 2015-11-17T22:55:04-0500
2 2015-11-18 03:55:08          America/Los_Angeles 2015-11-17T19:55:08-0800
3 2015-11-18 03:55:10 America/Indiana/Indianapolis 2015-11-17T22:55:10-0500
Run Code Online (Sandbox Code Playgroud)

更新2015-11-24

使用dplyr::combine()而不是unlist()允许变量保留具有正确时区属性的日期时间,而不是转换为字符串。

> get_local_time <- function(timestamp_utc, local_tz) {
    l <- lapply(seq(length(timestamp_utc)), 
                function(x) {with_tz(timestamp_utc[x], local_tz[x])})
    combine(l)
    }

> mutate(data, timestamp_local = get_local_time(timestamp_utc, tzone = local_tz))

Source: local data frame [3 x 3]

        timestamp_utc                     local_tz     timestamp_local
               (time)                        (chr)              (time)
1 2015-11-18 03:55:04             America/New_York 2015-11-17T22:55:04
2 2015-11-18 03:55:08          America/Los_Angeles 2015-11-17T19:55:08
3 2015-11-18 03:55:10 America/Indiana/Indianapolis 2015-11-17T22:55:10
Run Code Online (Sandbox Code Playgroud)