我只是引用了lubridate::parse_date_time()中的help page个,特别是它的select_format个论点.但我无法获得它并为我自己的用例设计我自己的函数.

实际上,我有几种格式的未清理日期.为了简单起见,让我们假设我有mdydmyymdydm格式的日期.

my_dates <- c("1988-02-03", "1988-15-03", "05-12-2023", "5-27-2022")

lubridate::parse_date_time(my_dates, orders = c("dmy","mdy", "ymd", 'ydm'))

#> [1] "1988-03-02 UTC" "1988-03-15 UTC" "2023-05-12 UTC" "2022-05-27 UTC"

在输出中,我希望dmy优先于mdy,ymd优先于ydm.我该怎么做呢?我的输出应该是-

#> [1] "1988-02-03 UTC" "1988-03-15 UTC" "2023-12-05 UTC" "2022-05-27 UTC"

推荐答案

默认情况下,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"

R相关问答推荐

使用Shiny组合和显示复制和粘贴的数据

在通过最大似然估计将ODE模型与数据匹配时,为什么要匹配实际参数的转换值?

R-更新面内部的栅格值

多个过滤器内的一个盒子在仪表板Quarto

使用列/行匹配将两个不同维度的矩阵相加

DEN扩展包中的RECT树形图出现异常行为

计算两列中满足特定条件连续行之间的平均值

是否有新方法来更改Facet_WRAP(Ggplot2)中条文本的文本 colored颜色 ?

从多个可选列中选取一个值到一个新列中

将多个变量组合成宽格式

如何将一列中的值拆分到R中各自的列中

'使用`purrr::pwalk`从嵌套的嵌套框架中的列表列保存ggplots时出现未使用的参数错误

使用列中的值来调用函数调用中应使用的其他列

R中治疗序列的相对时间指数

根据r中每行中的日期序列,使用列名序列创建新列

如何构建一个for循环来循环处理动物ID?

我需要使用ggplot2制作堆叠条形图

按两个因素将观测值分组后计算单独的百分比

如何在R中添加标识连续日期的新列

如何将一列相关性转换为R中的相关性矩阵