【问题标题】:Merging two time unit formats into one in R在R中将两种时间单位格式合并为一种
【发布时间】:2018-11-25 07:58:47
【问题描述】:

我有一个数据框,其中有一列包含描述工作时间的字符类型列。我想将该字符向量更改为数值,以便绘制图并推断它。一个困难在于有两种不同的格式:

我有 01.09:55:00 表示 1 天 9 小时 55 分 0 秒,或者如果没有达到一整天,04:30:00 表示 4 小时 30 分 0 秒。如果它变得更容易,将不会超过 100 天。小时,分钟,秒总是在那里,但不是天数,并且间隔不同。

我已经可以使用第二种格式来获取以分钟为单位的时间了:

MyData$Working_Time_Total = strptime(MyData$Working_Time_Total, 格式 = "%H:%M:%S") MyData$Working_Time_Total = (MyData$Working_Time_Total$sec + MyData$Working_Time_Total$min * 60 + MyData$Working_Time_Total$hour * 3600) / 60

我试图尝试一些在“.”上分开的拆分程序。然后以某种方式适当地重新组合它,但是如果没有“。”会导致问题。感谢您在此问题上的任何帮助,以获得我想要的结果,这是一个包含以分钟为单位的时间的数字向量。

【问题讨论】:

标签: r time split format duration


【解决方案1】:

我的解决方案可能有点小技巧,但它确实有效。但是,它不是矢量化的,对于大数据帧可能会很慢。

times <- c("04:30:00", "01.09:55:00")

# loop over "times" // rows of a column vector
for (i in 1:length(times)){
  # for format without days:
  if (nchar(times[i]) == 8){
    tmp <- as.numeric(unlist(strsplit(times[i], split = ":")))
    times[i] <- tmp[1] * 60 + tmp[2] + tmp[3] * 1/60 
  } else { # for format including days:
    tmp <- c(unlist(strsplit(times[i], split = "[.]")))
    tmp <- c(tmp[1], unlist(strsplit(tmp[2], split = ":")))
    tmp <- as.numeric(tmp)
    times[i] <- tmp[1] * 24 * 60 + tmp[2] * 60 + tmp[3] + tmp[4] * 1/60
  }
}

print(as.numeric(times))
# [1] 270  2035

【讨论】:

    【解决方案2】:

    这就是我在data.table 包中的as.ITime() 函数的帮助下要做的事情:

    times <- c("04:30:00", "01.09:55:00")
    
    library(data.table)
    cols <- c("days", "hms")
    as.data.table(times)[
      times %like% "[.]", (cols) := tstrsplit(times, "[.]")][
      is.na(days), (cols) := .( "0", times)][
        , as.integer(days) * 60 * 24 + as.integer(as.ITime(hms, "%H:%M:%S")) / 60][]
    
    [1]  270 2035
    

    基准测试

    # create benchmark data
    times0 <- CJ(c("", sprintf("%02i.", 1:99)), 1:24, 1:60)[, sprintf("%s%02i:%02i:00", V1, V2, V3)]
    
    # run benchmarks
    microbenchmark::microbenchmark(
      apitsch = {
        times <- copy(times0)
        for (i in 1:length(times)){
          # for format without days:
          if (nchar(times[i]) == 8){
            tmp <- as.numeric(unlist(strsplit(times[i], split = ":")))
            times[i] <- tmp[1] * 60 + tmp[2] + tmp[3] * 1/60 
          } else { # for format including days:
            tmp <- c(unlist(strsplit(times[i], split = "[.]")))
            tmp <- c(tmp[1], unlist(strsplit(tmp[2], split = ":")))
            tmp <- as.numeric(tmp)
            times[i] <- tmp[1] * 24 * 60 + tmp[2] * 60 + tmp[3] + tmp[4] * 1/60
          }
        }
        times
      },
      uwe = {
        times <- copy(times0)
        cols <- c("days", "hms")
        as.data.table(times)[
          times %like% "[.]", (cols) := tstrsplit(times, "[.]")][
            is.na(days), (cols) := .( "0", times)][
              , as.integer(days) * 60 * 24 + as.integer(as.ITime(hms, "%H:%M:%S")) / 60][]
      },
      times = 11L
      )
    
    Unit: milliseconds
        expr       min        lq      mean    median        uq      max neval cld
     apitsch 3485.6488 3561.5639 3708.8017 3631.2264 3747.1996 4288.368    11   b
         uwe  493.0976  497.6782  582.6732  540.5967  643.0875  773.587    11  a
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多