首页 > 解决方案 > 在 R 中创建具有多个时区的多个 POSIXlt 日期

问题描述

嗯,首先,我还是个菜鸟,正在学习 R。我有一个包含 90 万行和 36 列的数据集。在这些列中,假设 DATE 具有字符串格式的日期和另一列,假设 TZ 也具有字符串形式的时区。

我想要做的是将这两列收缩为一个类型为 POSIXlt 日期的列,它具有日期、时间、时区。这是我尝试获取所有转换日期的向量的代码:

# Let's suppose my data exist in a variable "data" with dates in "DATE" column and timezones in "TZ"

indices <- NULL
dates <- NULL

zones <- unique (data$TZ)

for(i in seq_along(zones)){
indices <<- which(data$TZ==zones[i])
dates <<- c(dates, as.POSIXlt(data$DATE[indices], format = "%m/%d/%Y %H:%M:%S", tz = zones[i]))
}

现在,虽然有大约 100 万次观察,但它似乎在 3-4 秒内完成了这项工作。只是,它“似乎”如此。我得到的结果是一个带有 NA 的列表。

当我尝试单独转换一个组时,它确实有效,即将每次迭代的结果存储在不同的变量中,或者不运行 for 循环并手动进行每次迭代,将每个结果存储在不同的变量中,最后连接这一切都使用c()功能。

我究竟做错了什么?

标签: rdatetimezoneposixctposixlt

解决方案


对于任何可能在这里绊倒的人,我想通了。

  1. 您不能c()在 POSIXlt 对象上使用,因为它会将其转换为本地时区。(不是 NA 的原因,但它很有帮助。)
  2. POSIXlt 存储为不同变量的列表,如 mday、zone 等,因此它的值不能在数据框元素中使用。我们可以使用 POSIXct 代替 POSIXlt,因为它在内部表示为 1970-01-01 的秒数。
  3. 由于我们将替换数据框列,dates因此使用将其转换为小标题会更容易dplyr::as_tibble(),然后使用它dplyr::rbind()来组合不同的结果。
  4. 引入 NA 的原因是 R 中的词法作用域。因此,我使用了indates <<- c(dates, as.POSIXlt(data$DATE[indices], format = "%m/%d/%Y %H:%M:%S", tz = zones[i]))的值是 NA 或未知。izones[i]

所以,正确的工作代码是 -

dates <- NULL

for (i in seq_along(zones)) {
    indices <- which(data$TZ==zones[i])
    dts <- as.POSIXct(data$BGN_DATE[indices], format = "%m/%d/%Y %H%M", tz = zones[i])
    dates <<- rbind(dates,as_tibble(dts))
}

#Further, to combine the dates into data frame
data <- arrange(data, TZ) %>% mutate(DATEandTime = dates$value) %>% select(-c("DATE","TZ"))


推荐阅读