【问题标题】:troubleshooting dates with ifelse()使用 ifelse() 排除故障日期
【发布时间】:2017-10-26 16:19:16
【问题描述】:

我有一个包含数万个条目的日期变量的数据框。我认为某处可能存在数据输入错误,因为我无法将其转换为日期类变量或在 lubridate() 中对其进行处理。

在这个 MWE 中,第一个观察结果 (a1) 是一个合法的日期,我希望我的日期是这样的格式。其他观察结果 (a2-a7) 代表不同类型的数据输入错误。我想测试 date 变量中的每个观察结果,以查看观察结果是否是预期格式的合法日期。

我尝试使用常规模式和 ifelse(),但无法让代码正常工作。我想最终得到类似 df2 的东西(尽管它不一定是数据框),这样我就可以轻松识别可能需要注意的任何日期变量观察的 ID。任何帮助将非常感激。

起点:

df1 <- data.frame(varID=c("a1","a2","a3","a4","a5","a6","a7"),varDate=c("01/01/2015","0101/2016","01/012017","35/01/2018","01/17/2019","01/01/20200","abc"))

期望的结果:

df2 <- data.frame(varID=c("a2","a3","a4","a5","a6","a7"),VarIssue=c("format issue","format issue","format issue","format issue","format issue","format issue"))

当前代码:

ifelse(df1$varDate == (^(0[1-9]|[12][0-9]|3[01])[- /.](0[1-9]|1[012])[- /.](19|20)\d\d$),"ok","format issue")

【问题讨论】:

  • 我可能遗漏了一些东西,但为什么不使用as.Date 使用“ok”format,并找到NA(“格式问题”):is.na(as.Date(df1$varDate, format = "%d/%m/%Y"))
  • 虽然我可以把它变成一个因素或字符,但它不会让我把它变成一个日期类变量。
  • @Henrik 我喜欢这个逻辑,但提供的正则表达式将接受多种日期格式,使用/-. 作为分隔符。
  • @Henrik 不应该像 as.Date('01-01-20000000', '%d-%m-%Y') 这样的东西不能像 as.Date('2000000-01-01', '%Y-%d-%m') 那样解析吗?
  • @rawr 否,“每个输入字符串都按照指定格式进行处理:忽略任何尾随字符。”(?strptime)。

标签: r


【解决方案1】:

两个问题,不能单独使用正则表达式,需要在接受正则表达式模式的函数中调用,并且需要双转义代词字符。

在 R 中,您必须像这样使用双重转义:\\d,因此您的模式变为:

 pattern <- '^(0[1-9]|[12][0-9]|3[01])[- /.](0[1-9]|1[012])[- /.](19|20)\\d\\d$'

我们使用grepl(它返回一个逻辑向量)来检查每一行:

df1$check <-  ifelse(grepl(pattern,df1$varDate)==TRUE,"ok", "format issue")

  varID     varDate        check
1    a1  01/01/2015           ok
2    a2   0101/2016 format issue
3    a3   01/012017 format issue
4    a4  35/01/2018 format issue
5    a5  01/17/2019 format issue
6    a6 01/01/20200 format issue
7    a7         abc format issue

【讨论】:

    【解决方案2】:

    也许下面的内容跑题了,但是如果你对日期格式有问题,可以考虑使用包lubridate,它的characterDate的转换函数可以识别大量格式,不要给它一出现麻烦就起来。

    library(lubridate)
    
    mdy(df1$varDate)
    #[1] "2015-01-01" "2016-01-01" "2017-01-01" NA           "2019-01-17"
    #[6] NA           NA          
    #Warning message:
    # 3 failed to parse.
    

    如您所见,只有3 failed to parse. 其他人被正确强制转换为Date 类。然后你会使用更简单的ifelse,但结果显然会大不相同。

    df3 <- data.frame(varID = df1$varID)
    df3$VarIssue <- ifelse(is.na(mdy(df1$varDate)), "format issue", "ok")
    df3
    #  varID     VarIssue
    #1    a1           ok
    #2    a2           ok
    #3    a3           ok
    #4    a4 format issue
    #5    a5           ok
    #6    a6 format issue
    #7    a7 format issue
    

    只有 3 个"format issue"

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-15
      • 2010-11-30
      • 2021-09-11
      • 2012-02-18
      • 2011-03-07
      • 1970-01-01
      相关资源
      最近更新 更多