with_tz与时区矢量

时间:2015-11-21 21:05:27

标签: r dplyr lubridate

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

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')
  )

我需要创建一个新变量,将UTC时间戳转换为local_tz列中定义的本地时间。但是,formatwith_tz(来自lubridate)只需要一个时区,而不是时区矢量。我正在寻找这样的事情:

mutate(data, timestamp_local = with_tz(timestamp_utc, tzone = local_tz))

有什么想法吗?

4 个答案:

答案 0 :(得分:3)

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

data$timestamp_utc <- as.POSIXct(data$timestamp_utc, tz = "UTC")

然后,您可以使用rowwise中的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"

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

答案 1 :(得分:0)

诀窍是在group_by()之前将local_tzmutate()一起使用:

data$timestamp_utc <- as.POSIXct(data$timestamp_utc, tz = "UTC")

data %>% 
  group_by(local_tz) %>%
  mutate(timestamp_local = with_tz(timestamp_utc, local_tz))

答案 2 :(得分:0)

data.table选项对我来说效果很好:

data[, timestamp_local := with_tz(timestamp_utc, local_tz), by=local_tz]

答案 3 :(得分:-1)

一个人可以向量化时区转换,如下所示

library(dplyr)
library(lubridate)

with_tz_utc <- function(ts, tz) force_tz(with_tz(ts, tz), 'UTC')
as_datetime_with_tz_utc <- compose(as_datetime, Vectorize(with_tz_utc))

现在照常使用mutate

data %>%
  mutate(
    timestamp_utc = as_datetime(timestamp_utc),
    timestamp_local = as_datetime_with_tz_utc(timestamp_utc, local_tz)
  )

另一种方法-速度要慢得多-可以将函数rowwisemutateungroup一起使用(还原rowwise

data %>%
  rowwise() %>%
  mutate(
    timestamp_utc = as_datetime(timestamp_utc),
    timestamp_local = with_tz_utc(timestamp_utc, local_tz)
  ) %>%
  ungroup()