我错过了什么吗?我无法弄清楚如何将以下内容转换为Dates:
ord_dates <- c("September 1st, 2016", "September 2nd, 2016",
"September 3rd, 2016", "September 4th, 2016")
Run Code Online (Sandbox Code Playgroud)
?strptime 似乎没有列出序数后缀的简写,并且它不是自动处理的:
as.Date(ord_dates, format = c("%B %d, %Y"))
#[1] NA NA NA NA
Run Code Online (Sandbox Code Playgroud)
是否有用于处理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"
Run Code Online (Sandbox Code Playgroud)
似乎这类数据应该比较常见; 我错过了什么吗?
享受以下的力量lubridate:
library(lubridate)
mdy(ord_dates)
[1] "2016-09-01" "2016-09-02" "2016-09-03" "2016-09-04"
Run Code Online (Sandbox Code Playgroud)
在内部,lubridate没有任何特殊的转换规范可以实现这一点.相反,lubridate首先使用(通过智能猜测)格式"%B %dst, %Y".这得到了第一个元素ord_dates.
然后它检查NAs并重复其对剩余元素的智能猜测,并"%B %dnd, %Y"着手获得第二个元素.它以这种方式继续,直到没有NA剩下(在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
Run Code Online (Sandbox Code Playgroud)
显而易见的优点lubridate是它的简洁性和灵活性.
| 归档时间: |
|
| 查看次数: |
431 次 |
| 最近记录: |