You need to enable JavaScript to run this app. R语言如何修改或删除不符合列正则模式的行,提取时间列小时值
优惠活动
大模型
产品
解决方案
定价
更多

R语言如何修改或删除不符合列正则模式的行,提取时间列小时值

混杂时间字段的小时值提取方法

实际场景

当前处理鲨鱼攻击事件数据集,需要从格式杂乱的时间字段提取小时值,用于24小时分箱的事件发生次数统计。
测试样例与预期输出:

Times <- c("12h00","16h30","Afternoon","15h00","14h20","7h30","06h00")
# 期望输出:["12","16",NA,"15","14","7","6"]

字段值的分布规则:

  • 绝大多数条目为##h##格式(如07h30)
  • 少量条目为#h##的单数字小时格式(如7h30)
  • 夹杂非标准时间文本(如Afternoon),这类值需要统一置为NA

最初的实现思路是用str_replace_all(Time, pattern, replacement)完成提取,初步想到的正则模式为"^\\d{2}h\\d{2}$",但存在两个未解决的问题:

  1. 不满足正则匹配规则的条目无法自动置为NA
  2. 无法覆盖单数字小时的时间格式

具体实现方案

适配stringr包的轻量实现

不需要硬靠str_replace_all做全量替换,直接用str_extract()匹配目标内容,未匹配到目标的位置会自动返回NA,天然解决非标准值转NA的问题:

library(stringr)
# 匹配规则:从字符串开头抓取1-2个连续数字,且该数字后面紧跟字母h
hour_vals <- str_extract(Times, "^\\d{1,2}(?=h)")

运行后输出结果:

[1] "12" "16" NA   "15" "14" "7"  "06"

如果需要把带前导0的06转换为对齐要求的6,只要把结果转成整数类型即可,整数转换会自动去掉前导0:

hour_vals <- as.integer(str_extract(Times, "^\\d{1,2}(?=h)"))
# 转换后结果:12 16 NA 15 14  7  6

说明:正则里的(?=h)是正向先行断言,只匹配h前面的数字,不会把h后面的分钟数误提取出来;设置\\d{1,2}的匹配长度,可以同时覆盖2位小时(如12h00)和1位小时(如7h30)的场景,不需要写多分支判断。

你之前设想的^\\d{2}h\\d{2}$存在两个适配问题:一是要求字符串必须是固定长度的两位数字+h+两位数字格式,匹配不到单数字小时的条目;二是如果用该模式做字符串替换,不匹配的条目会保留原始文本,不会自动转为NA,调整后的匹配逻辑可以同时解决这两个问题。

基础R原生实现(无需加载第三方包)

如果不想依赖外部包,用base R的字符串函数也能实现同等效果:

# 匹配「开头数字+h」的格式,把捕获到的第一组数字保留作为小时值
hour_vals <- sub("^(\\d{1,2})h.*$", "\\1", Times)
# 筛选出没被成功替换的非标准值,统一置为NA
hour_vals[!grepl("^\\d{1,2}h", Times)] <- NA
# 转成整数自动移除前导0
hour_vals <- as.integer(hour_vals)

运行结果和stringr方案完全一致。

后续直方图制作参考

提取完成的小时值可以直接传给绘图函数做分箱统计,不需要额外做区间预处理:

# 以0-24为区间边界做直方图
hist(hour_vals, breaks = 0:24, main = "鲨鱼攻击事件小时分布", xlab = "事件发生小时")

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.24 21:57:02