【问题标题】:R - How to remove dates from a string?R - 如何从字符串中删除日期?
【发布时间】:2018-03-14 19:55:21
【问题描述】:

我正在清理一个包含各种奇怪命名约定的表。我经常看到的名字之一是一串日期。其中一些名称包含可以使用的数字,但我想从字符串中删除日期格式。

编辑 - 日期采用 mm/YY 或 mm/YYYY 格式。正如我所见,日期通常是从 2017 年开始(我们需要更多最新更新)。

例如:

names <- c('IT Company 09/18',  'Tech Company 9/17', '9/2018 XYZ Company', '50/50 Phone Company')

应该是:

c('IT Company', 'Tech Company', 'XYZ Company', '50/50 Phone Company') 

我在这里尝试使用此函数来标记带有“/”和日期的字符串,但它也会提取不是日期的数字:

names2 <- names[grepl("[[:digit:]]", names) & grepl("/", names)]

输出

> names2
[1] "IT Company 09/18"   
[2] "Tech Company 9/17"  
[3] "9/2018 XYZ Company" 
[4] "50/50 Phone Company"

是否可以使用特定的日期表达式代替 [[:digit:]] 来查找带日期的字符串?

另外,从字符串中删除包含斜线的日期的函数是什么?

【问题讨论】:

  • 您希望哪些日期被视为日期/非日期? 10/10 是约会吗?在此示例中,您可以只包含 &amp; !grepl("50/50", names)
  • 我看到的日期是 mm/YY 或 mm/YYYY 格式。 10/10 不是日期,因为它是 dd/mm 格式。大约有 10 万条记录,我一直将“50/50 电话公司”之类的名称放入例外列表中。
  • 10/10 可能是 mm/YY
  • 你是对的。对于本练习,我们需要从 2017 年开始的最近日期。数据是最新的。我将编辑我的问题。

标签: r


【解决方案1】:

听起来像是 stringr 包的 string_remove_all 函数的工作。

诀窍是正确使用正则表达式模式。您没有想要的标准日期格式并且您希望保留 50/50 的事实让生活变得艰难。

这对我有用:

library('stringr')

date.pattern <- ' ?(0|1)?[1-9]/([0-9]{4}|[0-9]{2}) ?'

names <- c('IT Company 09/18',  'Tech Company 9/17', '9/2018 XYZ Company', '50/50 Phone Company')
str_remove_all(names, date.pattern)

那个正则表达式应该说

  • "日期是一个数字,或者是两个数字,其中第一个数字是 0 或 1。(假设第一个数字始终是一个月,对于单个数字的月份可能有前导零)。

  • 然后它(懒惰地)允许长度为 2 或 4 的年份。如果您知道您预计会遇到哪些年份,这可能会更精确。 “0001”可能不是您数据集中的年份。

  • 最后,它还会删除前导或尾随空格(如果存在),因为日期看起来可以出现在您关心的部分之前和之后,并且与您关心的部分用空格分隔。

输出

[1] "IT Company"          "Tech Company"        "XYZ Company"        
[4] "50/50 Phone Company"

也可以通过str_extract_all 运行它并检查输出以查看它们是否都有日期的外观。

【讨论】:

  • 感谢您的详细解释。我尝试使用 str_remove_all 函数,但出现此错误。 str_remove_all(names, date.pattern) 中的错误:找不到函数“str_remove_all”
  • 我找到了解决办法。 str_replace_all(names, date.pattern, "")
  • 如果您加载最新版本的stringr (1.3.0),str_rmove_all 将可用。
【解决方案2】:

我相信以下内容会满足您的要求。它使用正则表达式后跟trimws 来修剪结果开头和结尾的空白。

trimws(gsub("[[:digit:]]{1,4}/[[:digit:]]{1,4}", "", names))
#[1] "IT Company"    "Tech Company"  "XYZ Company"   "Phone Company"

【讨论】:

  • 如果我想删除所有号码但我想保留 50/50 电话公司,这可以工作。
【解决方案3】:

这是一个stringr 解决方案。这很复杂,因为很难仅通过查看某事物来判断它是否是日期:您需要检查您的输出并在有更多情况时调整此代码。第一个正则表达式捕获 1/2 位的格式,/01,假设任何日期都是 2000 年之后的一个数字。第二行去掉了数字,/然后是四位数。这很好地排除了50/50,但如果它被称为12/50 Phone Company 呢?这可以以某种日期格式解释为 1950 年 12 月。您必须确保不会意外排除任何类似的特殊情况,没有通用的方法来判断某事是否意味着日期。

我会阅读正则表达式;这是一个good resource 开始。

library(stringr)
names <- c('IT Company 09/18',  'Tech Company 9/17', '9/2018 XYZ Company', '50/50 Phone Company')

names %>%
  str_replace("\\d{1,2}/(0|1)\\d", "") %>%
  str_replace("\\d/\\d{4}", "") %>%
  str_trim()
#> [1] "IT Company"          "Tech Company"        "XYZ Company"        
#> [4] "50/50 Phone Company"

reprex package (v0.2.0) 于 2018 年 3 月 14 日创建。

【讨论】:

  • 这很棒。谢谢
猜你喜欢
  • 1970-01-01
  • 2014-11-16
  • 1970-01-01
  • 2017-05-05
  • 1970-01-01
  • 2013-05-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多