【问题标题】:Time format and calculations in RR中的时间格式和计算
【发布时间】:2021-03-26 10:28:42
【问题描述】:

我有以下数据框:

我有几个关于如何格式化和使用数据框的问题(我的所有列都是字符类型的变量)。

首先,有没有办法将 Start 列从字符变量重新格式化为时间类型变量。

就像 as.Date 格式化日期一样,R 中是否有 as.time 函数?

其次,我的 Start 和 Stop 列中有两个值没有正确显示为 24 小时时间格式,有什么方法可以将它们更改为以下内容:

24:46:00 到 0:46:00 和 25:14:00 到 01:14:00

第三,我想将日期和开始列合并为一列,如下所示:

2019-05-12 18:11

我尝试了以下方法: 但它给了我 N/As 作为新变量的值。

df$DT <- as.POSIXct(paste(df$Date, df$Start), format="%d-%m-%Y %H:%M:%S")

最后我想计算开始和停止时间之间的差异,我做了以下操作,它返回给我一条错误消息:

df$Time_diff = difftime(df$Stop, df$Start, units = "mins")

错误信息如下:

as.POSIXlt.character(x, tz, ...) 中的错误: 字符串不是标准的明确格式

谁能帮我解决以上四点(我想用base R编写代码而不导入任何库)?

谢谢!

【问题讨论】:

    标签: r date time format


    【解决方案1】:

    替代解决方案,使用基础 R:

    a
    # [1,] "25:45:00" "17:34" "2020-09-17"
    # [2,] "13:43"    "13:34" "2019-04-12"
    # [3,] "17:56:00" "12:45" "2019-11-03"
    
    b <- data.frame( t(apply(
     a[,1:2], 1, function(x) sapply(
     x, function(y) if(as.numeric(substr(y,1,2)) > 23){
     paste0(as.numeric(substr(y,1,2))-24,":",as.numeric(substr(y,4,5)) ) }
     else{ y } ) )), a[,3] )
    #         V1     a     a...3.
    # 1     1:45 17:34 2020-09-17
    # 2    13:43 13:34 2019-04-12
    # 3 17:56:00 12:45 2019-11-03
    
    cc <- data.frame( Start=as.POSIXlt(strptime( paste( b[,3], b[,1] ), "%Y-%m-%d %H:%M" )),
     Stop=as.POSIXlt(strptime( paste( b[,3], b[,2] ), "%Y-%m-%d %H:%M" ) ) )
    #                 Start                Stop
    # 1 2020-09-17 01:34:00 2020-09-17 17:34:00
    # 2 2019-04-12 13:43:00 2019-04-12 13:34:00
    # 3 2019-11-03 17:56:00 2019-11-03 12:45:00
    
    diff.Date(cc)
    #        Stop
    # 1  960 mins
    # 2   -9 mins
    # 3 -311 mins
    

    仅将时间(“17:45”)转换为 as.Date 最终总是会导致“最近的日期”+ 时间。

    【讨论】:

      【解决方案2】:

      “开始”列有不同的格式。一种选择是使用parse_date_time 正确解析不同的格式

      library(lubridate)
      parse_date_time(c("2019-05-12 18:11", "2019-10-20 24:46:00"),
             c("ymd HMS", "ymd HM"))
      #[1] "2019-05-12 18:11:00 UTC" "2019-10-21 00:46:00 UTC"
      

      使用 OP 的代码

      strt <- with(df, parse_date_time(paste(Date, Start), c("ymd HMS", "ymd HM")))
      stop <- with(df, parse_date_time(paste(Date, Stop), c("ymd HMS", "ymd HM")))
      

      现在我们执行difftime

      difftime(stop, strt, units = "mins")
      

      或者另一个选项是anytime

      library(anytime)
      anytime(c("2019-05-12 18:11", "2019-10-20 24:46:00"))
      

      如果“开始”、“停止”列只有两种格式,那么我们可以分两步完成

      fmt1 <- "%d-%m-%Y %H:%M:%S"
      fmt2 <- "%d-%m-%Y %H:%M" 
      strt <- with(df, as.POSIXct(paste(Date, Start), format = fmt1))
      i1 <- is.na(strt)
      str1[i1] <- with(df, as.POSIXct(paste(Date, Start)[i1], format = fmt2))
      stop <- with(df, as.POSIXct(paste(Date, Stop), format = fmt1))
      i2 <- is.na(stop)
      stop[i2] <- with(df, as.POSIXct(paste(Date, Stop[i2], format = fmt2))
      

      更新

      对于问题的第二部分,即。转换为24 hour句号

      str1 <- "25:14:00"
      sapply(strsplit(str1, ":"), function(x) {
           x1 <- as.numeric(x)
           i1 <- x[1] >= 24
            x1[1][i1] <- x1[1][i1] - 24
            do.call(sprintf, c(as.list(x1), fmt = "%02d:%02d:%02d"))
        })
      #[1] "01:14:00"
      

      【讨论】:

      • 感谢您的回复,有没有办法用 R 基础而不是库来做到这一点?
      • @Heng 您可以在base R 中针对不同格式分别执行此操作。但是,我认为使用包立即执行此操作会很方便吗?
      • @arkun 我可以通过执行以下 parse_date_time(start, "HMS") 将 Start 列格式化为适当的时间格式吗?
      • @Heng 您显示的图片中也有HMSMS 格式
      • @arkun 非常感谢您的帮助!
      猜你喜欢
      • 2020-05-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多