【问题标题】:Format for ordinal dates (day of month with suffixes -st, -nd, -rd, -th)序数日期的格式(带有后缀 -st、-nd、-rd、-th 的月份中的某天)
【发布时间】:2017-01-07 07:37:13
【问题描述】:

我错过了什么吗?我不知道如何将以下内容转换为Dates,其中月份中的某天 (%d) 具有序号后缀-st-nd-rd-th

ord_dates <- c("September 1st, 2016", "September 2nd, 2016",
               "September 3rd, 2016", "September 4th, 2016")

?strptime 似乎没有列出序数后缀的简写,并且不会自动处理:

as.Date(ord_dates, format = c("%B %d, %Y"))
#[1] NA NA NA NA

format 参数中是否有处理被忽略字符的标记?我丢失的令牌?

我能想到的最好办法是(可能有一个更短的正则表达式,但同样的想法):

as.Date(gsub("([0-9]+)(st|nd|rd|th)", "\\1", ord_dates), format = "%B %d, %Y")
# [1] "2016-09-01" "2016-09-02" "2016-09-03" "2016-09-04"

看来这类数据应该比较常见;我错过了什么吗?

【问题讨论】:

  • 这是一个较短的正则表达式:as.Date(sub("([0-9]+).*,", "\\1", ord_dates), format = c("%B %d %Y"))
  • 嗯,我不是正则表达式专家,但我想它应该是,当字符串很长并且第一个匹配在字符串的早期(所以它不必遍历其余部分)。
  • 关于你可以在 base 中做的最简单的事情:as.Date(sub('\\D+,', '', ord_dates), '%B %e %Y')。格式字符串中不是标记的所有内容都被视为文字(%% 除外,它被视为文字%),因此非常令人沮丧的是没有通配符。

标签: r date


【解决方案1】:

享受lubridate的力量:

library(lubridate)    
mdy(ord_dates)

[1] "2016-09-01" "2016-09-02" "2016-09-03" "2016-09-04"

在内部,lubridate 没有任何特殊的转换规范可以实现这一点。相反,lubridate 首先使用(通过聪明的猜测)格式"%B %dst, %Y"。这将获得ord_dates 的第一个元素。

然后它检查NAs 并对剩余的元素重复其智能猜测,确定"%B %dnd, %Y" 以获得第二个元素。它以这种方式继续下去,直到没有剩余的NAs(在这种情况下发生在 4 次迭代之后),或者直到它的智能猜测未能找到可能的格式候选。

您可以想象这会使lubridate 变慢,它确实 - 大约是使用上面@alistaire 建议的智能正则表达式的一半:

set.seed(109123)
ord_dates <- sample(
  c("September 1st, 2016", "September 2nd, 2016",
    "September 3rd, 2016", "September 4th, 2016"),
  1e6, TRUE
  )

library(microbenchmark)

microbenchmark(times = 10L,
               lubridate = mdy(ord_dates),
               base = as.Date(sub("\\D+,", "", ord_dates),
                              format = "%B %e %Y"))
# Unit: seconds
#       expr      min       lq     mean   median       uq      max neval cld
#  lubridate 2.167957 2.219463 2.290950 2.252565 2.301725 2.587724    10   b
#       base 1.183970 1.224824 1.218642 1.227034 1.228324 1.229095    10  a 

lubridate 的明显优势在于其简洁性和灵活性。

【讨论】:

    猜你喜欢
    • 2011-01-30
    • 2011-04-08
    • 1970-01-01
    • 2015-10-11
    • 1970-01-01
    • 1970-01-01
    • 2012-11-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多