Vectorised time zone conversion with lubridate

守給你的承諾、 提交于 2019-12-10 14:19:49

问题


I have a data frame with a column of date-time strings:

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

I want to convert these date-time strings to POSIX date-time objects with their respective timezones:

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

Error in mutate_impl(.data, dots) : Evaluation error: tz argument must be a single character string. In addition: Warning message: In if (tz != "UTC") { : the condition has length > 1 and only the first element will be used

I get the same result if I use ymd_hms without a timezone and pipe it into force_tz. Is it fair to conclude that lubridate doesn't support any sort of vectorisation when it comes to timezone operations?


回答1:


Another option is map2. It may be better to store different tz output in a list as this may get coerced to a single tz

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

If required, it can be unnested

out %>%
   unnest

The values in the list are

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"



回答2:


tz argument must be a single character string. indicates that there are more than one time zones thrown into ymd_hms(). In order to make sure that there is only one time zone being thrown into the function, I used rowwise(). Note that I am not in Australian time zone. So I am not sure if the outcome I have is identical to yours.

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


来源:https://stackoverflow.com/questions/48291932/vectorised-time-zone-conversion-with-lubridate

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!