首先,我还是一个傻瓜,正在学习R。我有一个90万行36列的数据集。在这些列中,一列(假设DATE(具有字符串格式的日期,另一列(假定TZ(也具有字符串形式的时区。
我想做的是将这两列压缩为一个POSIXlt-date类型的列,它有日期、时间和时区。以下是我尝试获取所有转换日期的矢量的代码:
# 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()
函数将其连接起来。
我做错了什么?
对于任何可能在这里绊倒的人,我都想好了。
- 不能在POSIXlt对象上使用
c()
,因为它会将其转换为本地时区。(不是NAs的原因,但它很有帮助。( - POSIXlt存储为不同变量的列表,如mday、zone等,因此它的值不能在数据帧元素中使用。我们可以使用POSIXct来代替POSIXlt,因为它在内部表示为1970-01-01中的秒
- 由于我们将用
dates
替换数据帧列,因此使用dplyr::as_tibble()
将其转换为tibble,然后使用dplyr::rbind()
组合不同的结果更容易 - 引入NA的原因是R中的词汇范围。我使用了
dates <<- c(dates, as.POSIXlt(data$DATE[indices], format = "%m/%d/%Y %H:%M:%S", tz = zones[i]))
,因此zones[i]
中i
的值为NA或未知
因此,正确的工作代码是-
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"))