使用 lubridate 进行矢量化时区转换
Vectorised time zone conversion with 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))
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
如果我在没有时区的情况下使用 ymd_hms
并将其通过管道传输到 force_tz
,我会得到相同的结果。就时区操作而言,可以断定 lubridate 不支持任何类型的矢量化吗?
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
另一种选择是map2
。最好将不同的 tz
输出存储在 list
中,因为这可能会被强制转换为单个 tz
library(tidyverse)
out <- testdf %>%
mutate(mydt_new = map2(mydt, mytz, ~ymd_hms(.x, tz = .y)))
如果需要,可以 unnest
ed
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"
我有一个包含一列日期时间字符串的数据框:
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))
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
如果我在没有时区的情况下使用 ymd_hms
并将其通过管道传输到 force_tz
,我会得到相同的结果。就时区操作而言,可以断定 lubridate 不支持任何类型的矢量化吗?
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
另一种选择是map2
。最好将不同的 tz
输出存储在 list
中,因为这可能会被强制转换为单个 tz
library(tidyverse)
out <- testdf %>%
mutate(mydt_new = map2(mydt, mytz, ~ymd_hms(.x, tz = .y)))
如果需要,可以 unnest
ed
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"