我在角色日期转换方面遇到问题,并希望能帮助您了解出现问题的原因。为此,我定义了一个包含两行的非常简单的数据框,其中包含每行的ID,时区,日期和时间。我想添加一个包含(例如)POSIXct条目的列,用于组合日期时间,包括正确的时区。 (这是一个合成示例,但我想将其应用于更大的数据集。)
首先,我们尝试使用R的基础设施将这些功能组合成数据,时间和时区的统一表示。
d <- data.frame(id=c(111, 222),
tzz=c("Europe/Berlin", "US/Eastern"),
d=c("09-Sep-2017", "11-Sep-2017"),
t=c("23:42:13", "22:05:17"),
stringsAsFactors = FALSE)
d$dt <- strptime(paste(d$d, d$t), tz=d$tzz, format="%d-%b-%Y %T")
Error in strptime(paste(d$d, d$t), tz = d$tzz, format = "%d-%b-%Y %T") :
invalid 'tz' value
这种方法失败了,虽然我不明白为什么。例如,我可以轻松地完成此非矢量化版本。此外,我使用的时区似乎是官方支持列表的一部分。
d$tzz %in% OlsonNames()
[1] TRUE TRUE
dt1 <- strptime(paste(d$d[1], d$t[1]), tz=d$tzz[1], format="%d-%b-%Y %T")
print(dt1)
[1] "2017-09-09 23:42:13 CEST"
print(tz(dt1))
[1] "Europe/Berlin"
dt2 <- strptime(paste(d$d[2], d$t[2]), tz=d$tzz[2], format="%d-%b-%Y %T")
print(dt2)
[1] "2017-09-11 22:05:17 EDT"
print(tz(dt2))
[1] "US/Eastern"
另外,考虑到我的问题可能是误解了如何使用strptime,然后我尝试了类似的方法与lubridate:
library(lubridate)
d$dt <- dmy_hms(paste(d$d, d$t), tz=d$tzz)
Error in strptime(.enclose(x), .enclose(fmt), tz) : invalid 'tz' value
但得到了同样的错误。同样,非矢量版本工作正常。
dt1l <- dmy_hms(paste(d$d[1], d$t[1]), tz=d$tzz[1])
print(dt1l)
[1] "2017-09-09 23:42:13 CEST"
print(tz(dt1l))
[1] "Europe/Berlin"
在tidyverse中尝试mutate会产生同样的问题。 (顺便说一句,CEST不属于OlsonNames集。)
非常感谢有关如何正确执行此操作的帮助,或者至少解释了这是如何出错的。
答案 0 :(得分:1)
尝试逐行计算:
library(dplyr)
d %>%
rowwise() %>%
mutate(ct = as.POSIXct(paste(d, t), format = "%d-%b-%Y %H:%M:%S", tz = tzz)) %>%
ungroup
,并提供:
# A tibble: 2 x 5
id tzz d t ct
<dbl> <chr> <chr> <chr> <dttm>
1 111. Europe/Berlin 09-Sep-2017 23:42:13 2017-09-09 17:42:13
2 222. US/Eastern 11-Sep-2017 22:05:17 2017-09-11 22:05:17
答案 1 :(得分:0)
类似于Gabor,但data.table
使用的是id是唯一的:
R> dt <- data.table(d)
R> dt[ , ct := as.POSIXct(paste(d, t), "%d-%b-%Y %H:%M:%S", tz=tzz), by=id][]
id tzz d t ct
1: 111 Europe/Berlin 09-Sep-2017 23:42:13 2017-09-09 17:42:13
2: 222 US/Eastern 11-Sep-2017 22:05:17 2017-09-11 22:05:17
R>