R 日期时间系列缺失值

R datetime series missing values

我正在从 chr 转换为 POSIXct,格式为 "%Y-%m-%d %H:%M:%S 但是,数据集中的某些时间没有秒部分 (%S)所以当我转换为 DateTime 时,没有秒的时间将作为空单元格返回 - NA 我如何确保这不会发生。我希望它们都作为 DateTime 返回,无论是否缺少某些时间部分?

这种格式的日期时间(“%Y-%m-%d %H:%M:%S”)被正确返回为 POSIXct

但是采用这种格式(“%Y-%m-%d %H:%M”)的日期时间返回为 NA

这是用于转换的代码 trips$ended_at <- as.POSIXct(trips$ended_at, format = "%Y-%m-%d %H:%M:%S") 这是一个拥有超过一百万个条目的庞大数据集,所以我什至不知道哪些日期时间没有秒部分。 有没有办法让那些没有秒部分的人只能有零和结尾? 例如,2020-29-04 01:57 在转换为 POSIXct

时将返回为 2020-29-04 01:57:00

请帮忙!

两种方法:

  1. 将文字 :00 连接到只有 hour/minute:

    的时间戳末尾
    as.POSIXct(trips$ended_at, format = "%Y-%m-%d %H:%M:%S")
    # [1] "2020-04-29 01:57:00 EDT" "2020-04-29 01:57:00 EDT"
    # [3] "2020-04-29 01:57:00 EDT" NA                       
    # [5] "2020-04-29 01:57:00 EDT"
    
    gsub("( [0-9]+:[0-9]+)$", "\1:00", trips$ended_at)
    # [1] "2020-04-29 01:57:00" "2020-04-29 01:57:00" "2020-04-29 01:57:00"
    # [4] "2020-04-29 01:57:00" "2020-04-29 01:57:00"
    
    as.POSIXct(gsub("( [0-9]+:[0-9]+)$", "\1:00", trips$ended_at), format = "%Y-%m-%d %H:%M:%S")
    # [1] "2020-04-29 01:57:00 EDT" "2020-04-29 01:57:00 EDT"
    # [3] "2020-04-29 01:57:00 EDT" "2020-04-29 01:57:00 EDT"
    # [5] "2020-04-29 01:57:00 EDT"
    
  2. 如果您有多种需要尝试的“候选”格式,您可以迭代地遍历它们。此循环遍历格式,将最有可能的候选人放在第一位。如果在任何时候所有时间戳都已转换,它会提前退出 for 循环。

    candidates <- c("%Y-%m-%d %H:%M", "%d/%m/%Y %H:%M:%S", "%d/%m/%Y %H:%M")
    out <- as.POSIXct(trips$ended_at, format = "%Y-%m-%d %H:%M:%S")
    for (fmt in candidates) {
      if (!length(isna <- is.na(out))) break
      out[isna] <- as.POSIXct(trips$ended_at[isna], format = fmt)
    }
    out
    # [1] "2020-04-29 01:57:00 EDT" "2020-04-29 01:57:00 EDT"
    # [3] "2020-04-29 01:57:00 EDT" "2020-04-29 01:57:00 EDT"
    # [5] "2020-04-29 01:57:00 EDT"
    

数据

trips <- data.frame(ended_at = c("2020-04-29 01:57:00", "2020-04-29 01:57:00", "2020-04-29 01:57:00", "2020-04-29 01:57", "2020-04-29 01:57:00"))

这是我通常做的事情。通过nchar()检查POSIXct格式化前的字符串长度,将结果存入新列,例如:

trips$check<-nchar(trips$ended_at)

然后检查所有 trips$ended_at 是否具有相同的长度,并为那些不具有相同长度的人添加缺失的秒数:

trips$ended_at_new<-ifelse(trips$check==19,trips$ended_at,paste(trips$ended_at,":00",sep=""))

您可以将 19 换成您正在使用的任何日期时间格式。重要说明:这仅在时间戳末尾缺少秒数的情况下有效,如果时间戳因任何其他原因少于 19 个字符则无效。

这是我采用的方法,使用 ifelse() 假设您正在处理两种可能性 - 有秒和没有秒

date_time <- c("2020-01-18 20:12:16", "2020-01-18 20:12")

ifelse(nchar(date_time) == 16, 
       format(as.POSIXct(date_time, format="%Y-%m-%d %H:%M"), "%Y-%m-%d %H:%M:%S"), 
       format(as.POSIXct(date_time, format="%Y-%m-%d %H:%M:%S"), "%Y-%m-%d %H:%M:%S"))