矢量化时区转换与lubridate

时间:2018-01-17 00:29:10

标签: r date datetime tidyverse lubridate

我有一个数据框,其中包含一列日期时间字符串:

library(tidyverse)
library(lubridate)

testdf = data_frame(
  mytz = c('Australia/Sydney', 'Australia/Adelaide', 'Australia/Perth'),
  mydt = c('2018-01-17T09:15:00', '2018-01-17T09:16:00', '2018-01-17T09:18:00'))

testdf

#  A tibble: 3 x 2
#   mytz               mydt
#   <chr>              <chr>
# 1 Australia/Sydney   2018-01-17T09:15:00
# 2 Australia/Adelaide 2018-01-17T09:16:00
# 3 Australia/Perth    2018-01-17T09:18:00

我想将这些日期时间字符串转换为具有各自时区的POSIX日期时间对象:

testdf %>% mutate(mydt_new = ymd_hms(mydt, tz = mytz))
  

mutate_impl(.data,dots)中的错误:     评估错误:tz参数必须是单个字符串。   另外:警告信息:   在if(tz!=“UTC”){:     条件的长度> 1,只使用第一个元素

如果我使用没有时区的ymd_hms并将其输入force_tz,我会得到相同的结果。可以公平地得出结论,当涉及时区操作时,lubridate不支持任何类型的矢量化吗?

2 个答案:

答案 0 :(得分:3)

另一个选项是map2。最好在tz中存储不同的list输出,因为这可能会被强制转换为单个tz

library(tidyverse)
out <- testdf %>%
         mutate(mydt_new = map2(mydt, mytz, ~ymd_hms(.x, tz = .y)))

如果需要,可以unnest编辑

out %>%
   unnest

list中的值

out %>%
   pull(mydt_new)
#[[1]]
#[1] "2018-01-17 09:15:00 AEDT"

#[[2]]
#[1] "2018-01-17 09:16:00 ACDT"

#[[3]]
#[1] "2018-01-17 09:18:00 AWST"

答案 1 :(得分:2)

tz argument must be a single character string.表示在ymd_hms()内投放了多个时区。为了确保只有一个时区被抛入函数中,我使用了rowwise()。请注意,我不在澳大利亚时区。所以我不确定我的结果是否与你的相同。

testdf <- data_frame(mytz = c('Australia/Sydney', 'Australia/Adelaide', 'Australia/Perth'),
                     mydt = c('2018-01-17 09:15:00', '2018-01-17 09:16:00', '2018-01-17 09:18:00'))

testdf %>% 
rowwise %>% 
mutate(mydt_new = ymd_hms(mydt, tz = mytz))

  mytz               mydt                mydt_new           
  <chr>              <chr>               <dttm>             
1 Australia/Sydney   2018-01-17 09:15:00 2018-01-17 06:15:00
2 Australia/Adelaide 2018-01-17 09:16:00 2018-01-17 06:46:00
3 Australia/Perth    2018-01-17 09:18:00 2018-01-17 09:18:00