R语言parse_date_time解析mdy格式日期不符合预期求助
lubridate::parse_date_time解析日期不符合预期的问题
问题描述
尝试使用lubridate包的parse_date_time函数,指定orders = c("mdy", "dmy")解析数据框的date2列,期望优先按**月/日/年(mdy)格式解析,当日值大于12时再按日/月/年(dmy)**格式解析。但实际解析结果不符合预期:
- "3/2/2012"被解析为
2012-02-03(预期为2012-03-02) - "2/8/2012"被解析为
2012-08-02(预期为2012-02-08)
相关代码及数据:
library(readxl) library(lubridate) data <- structure(list(date1 = c("5/13/2013", "5/4/2013", "5/15/2013", "4/17/2013", "12/20/2013", "26/02/2013", "4/17/2013"), date2 = c("22/9/2012", "26/2/2012", "29/11/2012", "3/2/2012", "3/20/2012", "29/11/2012", "2/8/2012"), date2b = c("22-Sep-12", "26-Feb-12", "29-Nov-12", "3-Feb-12", "20-Mar-12", "15-Aug-03", "12/17/2010"), date3 = c("40958", "41271", "40942", "40954", "40944", "22/9/2012", "14.05.2013"), date4 = c("2012/28/08", "2012/15/4", "2/3/2012", "2/15/2012", "2012/14/11", "2012/05/06", "14.05.2012"), date5 = c("2010-25-11", "2010-24-02", "2010-28-3", "6/19/2010", "5/11/2010", "26/02/2013","18/11/2010")), class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA,-7L)) parse_date_time(data$date2, orders = c("mdy", "dmy"))
实际输出:
[1] "2012-09-22 UTC" "2012-02-26 UTC" "2012-11-29 UTC" "2012-02-03 UTC" "2012-03-20 UTC" [6] "2012-11-29 UTC" "2012-08-02 UTC"
原因分析
parse_date_time的默认行为不是严格按照orders参数的顺序尝试解析,而是通过内置的select_formats函数统计每个格式能解析的日期数量,优先选择能解析最多行的格式。在你的date2列中,dmy格式能解析更多行(比如22/9/2012、26/2/2012这类日值大于12的日期只能用dmy解析),因此lubridate会用dmy解析所有能匹配该格式的日期,包括那些同时符合mdy格式的字符串(如3/2/2012),导致结果不符合预期。
解决方案
修改select_formats参数,让函数严格按照orders的顺序优先尝试第一个格式,解析失败的再尝试下一个格式。可以用select_formats = function(x) first(x)来实现:
parse_date_time(data$date2, orders = c("mdy", "dmy"), select_formats = function(x) first(x))
输出结果:
[1] "2012-09-22 UTC" "2012-02-26 UTC" "2012-11-29 UTC" "2012-03-02 UTC" "2012-03-20 UTC" [6] "2012-11-29 UTC" "2012-02-08 UTC"
该结果符合预期:
3/2/2012被解析为2012-03-02(mdy格式)2/8/2012被解析为2012-02-08(mdy格式)- 日值大于12的日期(如
22/9/2012)自动用dmy解析
内容的提问来源于stack exchange,提问作者Juergen Buesching
相关产品推荐
相关产品推荐

