【问题标题】:Using gsub to extract character string before white space in R使用gsub在R中的空格之前提取字符串
【发布时间】:2013-03-31 11:26:03
【问题描述】:

我有一个看起来像这样的生日列表:

dob <- c("9/9/43 12:00 AM/PM", "9/17/88 12:00 AM/PM", "11/21/48 12:00 AM/PM")

我只想从这个变量中获取日历日期(即在第一次出现空白之后删除所有内容)。

这是我迄今为止尝试过的:

dob.abridged <- substring(dob,1,8)
dob
[1] "9/9/43 1" "9/17/88 " "11/21/48"
dob.abridged <- gsub(" $","", dob.abridged, perl=T)
> dob.abridged
[1] "9/9/43 1" "9/17/88"  "11/21/48"

所以我的代码适用于长度为 6 或 7 的日历日期,但不适用于长度为 8 的日历日期。在更有效的正则表达式上是否有任何指针可以与 gsub 一起使用,以处理长度为 6、7 或 8 的日历日期?

谢谢。

【问题讨论】:

    标签: r


    【解决方案1】:

    不用substring,直接用gsub

    gsub( " .*$", "", dob )
    # [1] "9/9/43"   "9/17/88"  "11/21/48"
    

    一个空格 (),然后是任意字符 (.) 任意次数 (*),直到字符串结尾 ($)。请参阅?regex 了解正则表达式。

    【讨论】:

    • 我可以在这里分享的唯一建议是sub 就足够了,因为只有一个字符串结束位置。
    【解决方案2】:

    我经常使用strsplit 来解决这类问题,但我喜欢 Romain 的回答多么简单。我认为将 Romain 的解决方案与 strsplit 答案进行比较会很有趣:

    这是strsplit 解决方案:

    sapply(strsplit(dob, "\\s+"), "[", 1)
    

    使用 microbenchmark 包和 dob &lt;- rep(dob, 1000) 与原始数据:

    Unit: milliseconds
                                        expr       min        lq    median
                       gsub(" .*$", "", dob)  4.228843  4.247969  4.258232
     sapply(strsplit(dob, "\\\\s+"), "[", 1) 14.438241 14.558832 14.634638
            uq       max neval
      4.268029  5.081608  1000
     14.756628 53.344984  1000
    

    Win 7 机器上的明显赢家是来自 Romain 的 gsub 正则表达式。感谢罗曼的回答和解释。

    【讨论】:

      【解决方案3】:

      stringr 包含针对此问题量身定制的函数。

      library(stringr)
      word(dob,1)
      # [1] "9/9/43"   "9/17/88"  "11/21/48"
      

      【讨论】:

      • 将第二个参数更改为 -1 会提取最后一个空格之后的文本,这正是我想要的。即word(dob,-1)
      【解决方案4】:

      另一种仅提取日期的正则表达式模式

      library(stringr)
      str_extract(dob, regex("\\d{1,}\\/\\d{1,}\\/\\d{1,}"))
      #[1] "9/9/43"   "9/17/88"  "11/21/48"
      
      • \\d{1,}:至少匹配数字 1 次
      • \\/: 转义正斜杠

      【讨论】:

        【解决方案5】:

        从字母表中提取空格前字符的另一种方法是:

        你必须安装包:“stringr”

        stringr::str_extract(c("juan carlos", "miguel angel"), stringr::regex(pattern = "[a-z]+(?=\\s)", ignore_case = F))
        

        [a-z]:匹配 a 和 z 之间的每个字符(按 Unicode 代码点顺序)。

        +:1 个或更多。

        (?=\\s):前瞻,后跟 \s(即空格)(不匹配 \s)。

        更多信息:https://stringr.tidyverse.org/articles/regular-expressions.html

        【讨论】:

          猜你喜欢
          • 2015-12-22
          • 2016-11-17
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多