【问题标题】:Extract dates from strings in R从R中的字符串中提取日期
【发布时间】:2016-06-18 16:39:15
【问题描述】:

我有一个字符串向量,如下所示。我想提取日期。

check_values <- c("deficit based on wage statement 7/14/ to 7/17/2015",
                "Deficit Due: $1205.73 -$879.63= $326.10 x 70%=$228.2",
                "Deficit Due for 12 wks pd - 7/14/15 thru 10/5/15;",
                "Deficit due to wage statement: 4/22/15 thru 5/12/15",
                "depos transcript 7/10/15 for 7/8/15 depos",
                "difference owed for 4/25/15-5/22/15",
                "tpd 4:30:2015 - 5:22:2015",
                "Medical TREATMENT DATES:  6/30/2015 -  6/30/2015",
                "4/25/15-5/22/15",
                "Medical")

                check_values <- as.data.table(check_values)
                names(check_values) <- "check_memo"

在提取日期之前,我想创建一个 Date_Flag。我使用了以下代码,但它给出了不同的输出:

check_values$Date_Flag <- ifelse(grepl("([0-9]+)(/|-|:)([0-9]+)(/|-|:)([0-9]+)(/|-|:)", check_values$check_memo), 1, 0)
 #[1] FALSE FALSE FALSE FALSE FALSE  TRUE FALSE FALSE  TRUE FALSE
 #Expected Output: FALSE FALSE TRUE TRUE TRUE TRUE TRUE TRUE TRUE FALSE

创建此 Date_Flag 后,我想提取日期(两个部分)。有人可以告诉我上述常规回归有什么问题吗?

谢谢

【问题讨论】:

  • 正则表达式的结尾是:(/|-|:),这是主要问题,因为只有少数日期后跟/-:。所以这就是问题所在。您还可以在不需要捕获组并且使用不必要的 ifelse 语句时使用它们。 grepl 返回 TRUE 或 FALSE。无需使用ifelse
  • @Jota - 感谢您指出我的脚本存在的问题。你能解释一下 (/|:) 和 [/:] 之间的确切区别吗?为什么一个工作而另一个不工作?我同意你的观点,不需要 ifelse。此外,为什么我不能使用 [0-9]+ 而不是 [0-9]{1,2}?虽然 second 限制了位数,但我的目的应该可以通过两者来实现。如果我错了,请纠正我。
  • 评论不是完整解释您的问题的正确位置,但我会建议一些搜索词。方括号用于character classes,括号用于capturing and grouping。此外,请查看?regex 帮助页面并查找有关正则表达式的教程以了解更多信息。如果之后您仍有问题,请考虑发布一个新问题。
  • @Jota - 我明白了。感谢您提供合适的指点。我一定会通读的。

标签: regex r date data.table


【解决方案1】:

我们可以使用str_count 来创建“Date_Flag”,其中假设如果“check_memo”的每个元素中有 2 个完整日期,我们将得到 TRUE 或 FALSE。

library(data.table)
library(stringr)
pat <- "[0-9]{1,2}[/:][0-9]{1,2}[/:][0-9]{2,4}"
check_values[,Date_Flag := str_count(check_memo, pat)==2]
check_values
#                                             check_memo Date_Flag
#1:   deficit based on wage statement 7/14/ to 7/17/2015     FALSE
#2: Deficit Due: $1205.73 -$879.63= $326.10 x 70%=$228.2     FALSE
#3:    Deficit Due for 12 wks pd - 7/14/15 thru 10/5/15;      TRUE
#4:  Deficit due to wage statement: 4/22/15 thru 5/12/15      TRUE
#5:            depos transcript 7/10/15 for 7/8/15 depos      TRUE
#6:                  difference owed for 4/25/15-5/22/15      TRUE
#7:                            tpd 4:30:2015 - 5:22:2015      TRUE
#8:     Medical TREATMENT DATES:  6/30/2015 -  6/30/2015      TRUE
#9:                                      4/25/15-5/22/15      TRUE
#10:                                             Medical     FALSE

如果我们需要提取日期,请使用与 str_extract_all 相同的模式

check_values[(Date_Flag),  paste0("Date", 1:2) := 
                  transpose(str_extract_all(check_memo, pat))]

check_values
                                              check_memo #Date_Flag     Date1     Date2
# 1:   deficit based on wage statement 7/14/ to 7/17/2015     FALSE        NA        NA
# 2: Deficit Due: $1205.73 -$879.63= $326.10 x 70%=$228.2     FALSE        NA        NA
# 3:    Deficit Due for 12 wks pd - 7/14/15 thru 10/5/15;      TRUE   7/14/15   10/5/15
# 4:  Deficit due to wage statement: 4/22/15 thru 5/12/15      TRUE   4/22/15   5/12/15
# 5:            depos transcript 7/10/15 for 7/8/15 depos      TRUE   7/10/15    7/8/15
# 6:                  difference owed for 4/25/15-5/22/15      TRUE   4/25/15   5/22/15
# 7:                            tpd 4:30:2015 - 5:22:2015      TRUE 4:30:2015 5:22:2015
# 8:     Medical TREATMENT DATES:  6/30/2015 -  6/30/2015      TRUE 6/30/2015 6/30/2015
# 9:                                      4/25/15-5/22/15      TRUE   4/25/15   5/22/15
#10:                                              Medical     FALSE        NA        NA

【讨论】:

  • 非常感谢您的详细回复。这真的很有帮助。如果有任何其他问题,我会发布。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-17
  • 2016-06-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多