默认情况下,parse_date_time()
基于所提供的orders
生成strptime()
个日期格式的集合(例如,%Y-%m-%d
),对照日期的子集来训练这些格式,并且这些格式通过相对于训练数据的匹配次数来排序,并且基于格式中的令牌的数目和某些令牌的存在来应用权重.
要按顺序使用从orders
猜到的格式,可以设置train = FALSE
.
library(lubridate)
my_dates <- c("1988-02-03", "1988-15-03", "05-12-2023", "5-27-2022")
my_orders <- c("dmy","mdy", "ymd", 'ydm')
parse_date_time(my_dates, my_orders, train = FALSE)
[1] "1988-02-03 UTC" "1988-03-15 UTC" "2023-12-05 UTC" "2022-05-27 UTC"
如果您想要按预期使用select_format
参数,那么逐步了解正在发生的事情可能会很有用.文档说明了论点所采取的方法
从一组格式中 Select 要解析的实际格式的函数
它与x的训练子集匹配.它接收一个命名整数
向量,并返回选定格式的字符向量.姓名或名称
输入向量是与训练相匹配的格式(而不是顺序
准备好了.
我们可以通过拨打guess_formats()
看到猜到的格式:
(guesses <- guess_formats(my_dates, my_orders))
dOmy Omdy Omdy yOmd ydOm ydOm dmy mdy mdy ymd ydm
"%d-%Om-%Y" "%Om-%d-%Y" "%Om-%d-%Y" "%Y-%Om-%d" "%Y-%d-%Om" "%Y-%d-%Om" "%d-%m-%Y" "%m-%d-%Y" "%m-%d-%Y" "%Y-%m-%d" "%Y-%d-%m"
ydm
"%Y-%d-%m"
由于可以多次猜测相同的格式,因此只需要唯一的格式:
guesses <- unique(guesses)
根据训练集对这些格式进行测试,以查看每种格式返回的有效转换数:
lubridate:::.train_formats(my_dates, guesses, "")
%Om-%d-%Y %Y-%d-%Om %m-%d-%Y %Y-%d-%m %d-%Om-%Y %Y-%Om-%d %d-%m-%Y %Y-%m-%d
2 2 2 2 1 1 1 1
默认情况下,该命名向量随后被传递给.select_formats
函数,该函数对格式进行加权和排序.您可以判断未导出的函数,以查看应用于某些令牌的默认权重:
lubridate:::.select_formats
function (trained, drop = FALSE)
{
nms <- names(trained)
score <- nchar(gsub("[^%]", "", nms)) + grepl("%Y", nms,
fixed = T) * 1.5 + grepl("%y(?!%)", nms, perl = T) *
1.6 + grepl("%[Bb]", nms) * 0.31 + grepl("%Om", nms) *
0.3 + grepl("%Op", nms) * 0.3 + grepl("%Ob", nms) * 0.32
n0 <- trained != 0
if (drop) {
score <- score[n0]
trained <- trained[n0]
}
else {
score[!n0] <- -100
}
names(trained)[order(score, trained, decreasing = T)]
}
当您呼叫parse_date_time(my_dates, my_orders)
时,格式的默认优先级为:
lubridate:::.select_formats(lubridate:::.train_formats(my_dates, guesses, locale = ""))
[1] "%Om-%d-%Y" "%Y-%d-%Om" "%d-%Om-%Y" "%Y-%Om-%d" "%m-%d-%Y" "%Y-%d-%m" "%d-%m-%Y" "%Y-%m-%d"
要改变这一点,我们可以提供一个定制函数来应用不同的权重,即优先排序以%d-%m
开头的格式优先于%m-%d
,以%Y-%m
开头的格式优先于%Y-%d
.
my_select <- function(trained) {
nms <- names(trained)
score <- nchar(gsub("[^%]", "", nms)) + grepl("^%d-%O?m", nms) * 2 + grepl("^%Y-%O?m", nms) * 2
nms[order(score, trained, decreasing = TRUE)]
}
利用这一点,现在的优先事项是:
my_select(lubridate:::.train_formats(my_dates, guesses, locale = ""))
[1] "%d-%Om-%Y" "%Y-%Om-%d" "%d-%m-%Y" "%Y-%m-%d" "%Om-%d-%Y" "%Y-%d-%Om" "%m-%d-%Y" "%Y-%d-%m"
如果我们在parse_date_time()
中使用它,我们会得到您想要的结果:
parse_date_time(my_dates, orders, select_formats = my_select)
[1] "1988-02-03 UTC" "1988-03-15 UTC" "2023-12-05 UTC" "2022-05-27 UTC"
值得注意是,另一种替代方法是使用parse_date_time2
并将strptime
格式直接传递给orders
:
parse_date_time2(my_dates, orders = c("%d-%m-%Y","%m-%d-%Y", "%Y-%m-%d", '%Y-%d-%m'))
[1] "1988-02-03 UTC" "1988-03-15 UTC" "2023-12-05 UTC" "2022-05-27 UTC"