如何快速将多格式日期向量统一转换为yyyy-mm-dd格式?
统一转换多格式日期向量的高效解决方案
问题背景
我有一个包含数百万条记录的日期向量,其中存在多种不一致的日期格式,示例如下:
dates = c("2018-11-06", "11/6/2018", "11-6-2018")
需要将其统一转换为2018-11-06(YYYY-MM-DD)格式。此前尝试的方案要么执行速度极慢,要么结果仅部分正确:
anytime::anydate(dates) as.Date(lubridate::parse_date_time(dates, '%m-%d-%Y')) # 结果仅部分正确
高效准确的解决方案
经过性能基准测试,以下两个方案在速度和准确性上表现最优:
方案1:Wimpel(速度最快)
通过字符串替换统一分隔符,调整日期格式后调用fasttime::fastDate处理,性能最优:
dates_1 = gsub("/", "-", dates) dates_2 = ifelse(grepl("^[0-9]{1,2}.[0-9]{1,2}.[0-9]{4}$", dates_1), gsub("^([0-9]{1,2}).([0-9]{1,2}).([0-9]{4})$", "\\3-\\1-\\2", dates_1), dates_1) fasttime::fastDate(dates_2)
方案2:user2974951_2(易理解且速度较快)
使用fast_strptime直接匹配多种日期格式,再截取日期部分,逻辑清晰且性能优异:
substr(fast_strptime(dates,c("%Y-%m-%d","%d/%m/%Y","%d-%m-%Y")), 1, 10)
性能基准测试
使用microbenchmark进行10次重复测试,结果如下:
测试代码
microbenchmark::microbenchmark( user2974951_1 = substr(parse_date_time(dates, c("%Y-%m-%d","%d/%m/%Y","%d/%m/%Y")), 1, 10), user2974951_2 = substr(fast_strptime(dates,c("%Y-%m-%d","%d/%m/%Y","%d-%m-%Y")), 1, 10), Wimpel = { dates_1 = gsub("/", "-", dates) dates_2 = ifelse(grepl("^[0-9]{1,2}.[0-9]{1,2}.[0-9]{4}$", dates_1), gsub("^([0-9]{1,2}).([0-9]{1,2}).([0-9]{4})$", "\\3-\\1-\\2", dates_1), dates_1) fasttime::fastDate(dates_2) }, TarJae = substr(parse_date_time(dates, orders=c("ymd", "mdy")), 1, 10), times = 10)
测试结果
Unit: microseconds expr min lq mean median uq max neval cld user2974951_1 7070.939 7147.098 7385.8261 7238.3540 7520.453 8193.161 10 b user2974951_2 319.894 355.736 404.0914 372.4270 415.670 707.338 10 a Wimpel 112.448 130.324 148.4439 152.1875 159.463 190.922 10 a TarJae 6123.001 6140.183 6959.6301 6277.1425 6838.099 12173.134 10 b
问题保留说明
请勿关闭此问题,现有相关方案仅适用于日期格式一致的场景,而本问题针对的是多不一致日期格式的批量处理需求,具有独特性。
内容的提问来源于stack exchange,提问作者Saurabh
相关产品推荐
相关产品推荐

