我得到了一个包含纬度,经度,本地日期和本地时间字段的海量数据集。我正在尝试将此信息组织到ISO UTC时间字段中。我的代码有问题,因为当数据中存在多个时区时,我不知道如何使用as.POSIXct()。每当我尝试在tz =部分中使用数组或循环时,都会收到错误消息。
我使用了lutz包中的tz_lookup_coords()函数来定义数据帧中每一行的时区。我还能够将数据过滤到单个时区,并成功使用as.POSIXct()和format()函数获取UTC时间。但是,我想要一个更优雅的解决方案,将单个代码应用于整个数据集。
sample<- data.frame(
"localDate" = c("2015-04-20","2016-07-17","2015-08-06"),
"localTime" = c("14:00", "14:46", NA ),
"timeZone" = c("Pacific/Pago_Pago", NA , "Pacific/Honolulu")
)
# Change times from local to UTC
sample$localDateTime <- paste(sample$localDate, sample$localTime, sep = " ")
for (i in 1:nrow(sample)) {
sample[i,]$localDateTime <- as.POSIXct(sample[i,]$localDateTime, tz= sample[i,]$timeZone, "%Y-%m-%d %H:%M")
}
sample$eventDate <- format(sample$localDateTime, tz= "UTC", usetz = TRUE)
当我输入“太平洋/檀香山”之类的单个时区时,代码可以很好地工作,但它将每一行都当作一个时区来对待。
> sample
localDate localTime timeZone localDateTime eventDate
1 2015-04-20 14:00 Pacific/Pago_Pago 2015-04-20 14:00 2015-04-21 00:00:00 UTC
2 2016-07-17 14:46 Pacific/Saipan 2016-07-17 14:46 2016-07-18 00:46:00 UTC
3 2015-08-06 10:35 Pacific/Honolulu 2015-08-06 10:35 2015-08-06 20:35:00 UTC
如果我尝试在函数的tz =部分中使用除引号中的字符串以外的其他字符,则会收到以下代码:
Error in strptime(x, format, tz = tz) : invalid 'tz' value
答案 0 :(得分:0)
library(lubridate)
sample <-
data.frame(
"localDate" = c("2015-04-20","2016-07-17","2015-08-06"),
"localTime" = c("14:00", "14:46", "10:35"),
"timeZone" = c("Pacific/Pago_Pago", "Pacific/Saipan", "Pacific/Honolulu")
)
sample$localDateTime <-
paste(sample$localDate, sample$localTime, sep = " ")
list <-
list()
for (i in 1:nrow(sample)){
list[[i]] <-
ymd_hm(sample$localDateTime[i],
tz = as.character(sample$timeZone[i]))
}
list
R> list
[[1]]
[1] "2015-04-20 14:00:00 SST"
[[2]]
[1] "2016-07-17 14:46:00 ChST"
[[3]]
[1] "2015-08-06 10:35:00 HST"
答案 1 :(得分:0)
该错误是由于timeZone
列是一个因素而不是字符向量,请在定义data.frame时使用stringsAsFactors = FALSE
将timeZone
指定为字符列。您还可以通过使用lubridate
包中的矢量化函数来避免任何循环:
library(lubridate)
df <- data.frame(
"localDate" = c("2015-04-20","2016-07-17","2015-08-06"),
"localTime" = c("14:00", "14:46", "10:35"),
"timeZone" = c("Pacific/Pago_Pago", "Pacific/Saipan", "Pacific/Honolulu"),
stringsAsFactors = FALSE
)
df$eventDate <- force_tzs(ymd_hm(with(df, paste(localDate, localTime))), tzones = df$timeZone)
df
#> localDate localTime timeZone eventDate
#> 1 2015-04-20 14:00 Pacific/Pago_Pago 2015-04-21 01:00:00
#> 2 2016-07-17 14:46 Pacific/Saipan 2016-07-17 04:46:00
#> 3 2015-08-06 10:35 Pacific/Honolulu 2015-08-06 20:35:00
编辑:如果缺少值,请检查每一行是否可以转换,如果不能返回NA
。下面是使用基数R的示例解决方案:
df <- data.frame(
"localDate" = c("2015-04-20","2016-07-17","2015-08-06", "2019-01-01", "2019-01-01"),
"localTime" = c("14:00", "14:46", "10:35", NA, "00:00"),
"timeZone" = c("Pacific/Pago_Pago", "Pacific/Saipan", "Pacific/Honolulu",
"Pacific/Honolulu", NA),
stringsAsFactors = FALSE
)
df$eventDate <- apply(df, 1, function(row) {
ifelse(any(is.na(row)), NA_character_,
format(as.POSIXct(paste(row["localDate"], row["localTime"]), "%Y-%m-%d %H:%M",
tz = row["timeZone"]), tz = "UTC", usetz = TRUE)
)
})
df
#> localDate localTime timeZone eventDate
#> 1 2015-04-20 14:00 Pacific/Pago_Pago 2015-04-21 01:00:00 UTC
#> 2 2016-07-17 14:46 Pacific/Saipan 2016-07-17 04:46:00 UTC
#> 3 2015-08-06 10:35 Pacific/Honolulu 2015-08-06 20:35:00 UTC
#> 4 2019-01-01 <NA> Pacific/Honolulu <NA>
#> 5 2019-01-01 00:00 <NA> <NA>