You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用R语言extract解析多格式run_time列并补全缺失分量

解决Slurm日志run_time字段解析问题

针对Slurm日志中run_time的三种格式(天-时:分:秒、时:分、分:秒),可以通过以下几种方法解析为days、hours、minutes、seconds字段,缺失分量自动填充为0:

方案一:dplyr::extract + 正则匹配

利用正则表达式捕获所有可选的时间分量,再将空值替换为0并转换为整数类型:

library(dplyr)

# 构造示例数据
df <- tibble(
  username = c("user1", "user2", "user3", "user4"),
  cpus = c(2, 4, 1, 8),
  run_time = c("2-03:45:12", "05:30", "10:05", "1-12:00:00")
)

# 解析run_time
result <- df %>%
  # 正则捕获可选的days、hours,必选的minutes和可选的seconds
  extract(run_time, 
          into = c("days", "hours", "minutes", "seconds"),
          regex = "^(?:(\\d+)-)?(?:(\\d+):)?(\\d+)(?::(\\d+))?$",
          remove = FALSE) %>%
  # 将缺失的分量替换为0
  mutate(across(c(days, hours, minutes, seconds), ~ ifelse(is.na(.), 0, .))) %>%
  # 转换为整数类型
  mutate(across(c(days, hours, minutes, seconds), as.integer))

print(result)

正则说明:

  • ^(?:(\\d+)-)?:可选的天数部分,匹配数字-,捕获数字到days组
  • (?:(\\d+):)?:可选的小时部分,匹配数字:,捕获数字到hours组
  • (\\d+):必选的分钟/小时/分钟部分(根据格式自动匹配),捕获到minutes组
  • (?::(\\d+))?$:可选的秒数部分,匹配:数字,捕获数字到seconds组

方案二:dplyr::separate_wider_regex(dplyr 1.1.0+)

如果使用较新版本的dplyr,separate_wider_regex可以更直观地定义每个时间分量的模式,自动处理可选部分:

library(dplyr)

result <- df %>%
  separate_wider_regex(
    run_time,
    patterns = list(
      days = "(\\d+)?",    # 可选的天数
      sep1 = "-?",         # 可选的分隔符-
      hours = "(\\d+)?",   # 可选的小时
      sep2 = ":?",         # 可选的分隔符:
      minutes = "(\\d+)",  # 必选的分钟
      sep3 = ":?",         # 可选的分隔符:
      seconds = "(\\d+)?"  # 可选的秒数
    ),
    remove = FALSE
  ) %>%
  select(-starts_with("sep")) %>%  # 移除临时分隔符列
  mutate(across(c(days, hours, seconds), ~ ifelse(is.na(.), 0, .))) %>%
  mutate(across(c(days, hours, minutes, seconds), as.integer))

print(result)

方案三:lubridate处理时长

通过统一格式后转换为duration对象,再提取各时间分量:

library(dplyr)
library(lubridate)

result <- df %>%
  mutate(
    # 统一run_time格式为lubridate可识别的时长字符串
    run_time_clean = case_when(
      # 处理天-时:分:秒格式,转换为"X days HH:MM:SS"
      str_detect(run_time, "^\\d+-\\d+:\\d+:\\d+$") ~ str_replace(run_time, "^(\\d+)-", "\\1 days "),
      # 处理时:分格式,补全秒为00
      str_detect(run_time, "^\\d+:\\d+$") ~ paste0(run_time, ":00"),
      # 处理分:秒格式,补全小时为00
      str_detect(run_time, "^\\d+:\\d+$") ~ paste0("00:", run_time),
      TRUE ~ run_time
    ),
    # 转换为duration对象
    dur = duration(run_time_clean),
    # 提取各时间分量
    days = as.integer(dur %/% ddays(1)),
    hours = as.integer((dur %% ddays(1)) %/% dhours(1)),
    minutes = as.integer((dur %% dhours(1)) %/% dminutes(1)),
    seconds = as.integer(dur %% dminutes(1))
  ) %>%
  select(-run_time_clean, -dur)  # 移除临时列

print(result)

内容的提问来源于stack exchange,提问作者lonestar21

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 06:27:51