【问题标题】:Using grepl in R在 R 中使用 grepl
【发布时间】:2015-06-13 17:18:57
【问题描述】:

在哪些情况下,这两种不同的实现方式会产生不同的结果?

data(mtcars)
firstWay <- mtcars[grepl('6',mtcars$cyl),]
SecondWay <- mtcars[mtcars$cyl=='6',]

如果这些方法总是给出相同的结果,那么推荐哪种方法?为什么?谢谢

【问题讨论】:

    标签: r grepl


    【解决方案1】:

    mtcars$cyl 是一个数字列,因此最好将其与使用 mtcars[mtcars$cyl == 6, ] 的数字进行比较。

    但等式运算符==grepl 之间的区别在于,== 仅适用于等于"6" 的向量成员,而grepl 将匹配向量的任何成员向量中任何地方都有一个 6。

    所以,例如:

    String                                                   ==     grepl
    6                                                        TRUE   TRUE
    123456                                                   FALSE  TRUE
    6ABC                                                     FALSE  TRUE
    This is a long sentence which happens to have a 6 in it  FALSE  TRUE
    Whereas this long sentence does not                      FALSE  FALSE
    

    等效的grepl 模式将是“^6$”。 http://www.regular-expressions.info/tutorial.html 有一个关于正则表达式的教程(其中之一)。

    【讨论】:

      【解决方案2】:

      嗯,我认为第一个区别是 grepl 即使您还不知道,您也可以进行子集化,例如 6,但您可以尝试搜索以 6 开头或结尾的行.

      如果您尝试使用常规子集技术来执行此操作,您将得到一个空对象,因为例如^6,它不会被识别为正则表达式,而是被识别为带有符号^6 的字符串。

      我相信还有其他区别,但我相信专业用户会提供更详细的答案。

      对于可能首选的操作系统,可能有效率的原因:

      system.time(mtcars[grepl('^6',mtcars$cyl),])
         user  system elapsed 
        0.029   0.002   0.035 
      system.time(mtcars[mtcars$cyl=='6',])
         user  system elapsed 
        0.031   0.002   0.046 
      

      这个小例子可能只是一个指南,正如@Nick K 建议的那样,首先必须对microbenchmark 进行进一步(和精确)的调查。当然,对于大数据集,我几乎不相信专业用户(或需要速度的用户)会喜欢它们,但也许它会依赖数据表,或者像dplyr 这样的工具,用低级语言编写,所以速度更快。

      【讨论】:

      • system.time 对于像这样的快速表达式并没有多大用处。 microbenchmark @CactusWoman 的回答要好得多。
      【解决方案3】:

      使用包微基准,我们可以看到哪个更快

      library(microbenchmark)
      m <- microbenchmark(mtcars[grepl('6',mtcars$cyl),], mtcars[mtcars$cyl=='6',], times=10000)
      
          Unit: microseconds
                               expr     min      lq     mean  median      uq      max neval
       mtcars[grepl("6", mtcars$cyl), ] 229.080 234.738 247.5324 236.693 239.417 6713.914 10000
            mtcars[mtcars$cyl == "6", ] 214.902 220.210 231.0240 221.956 224.471 7759.507 10000
      

      看起来== 更快,所以你应该尽可能使用它

      但是,这些函数的作用并不完全相同。 grepl 搜索字符串是否存在,== 检查表达式是否相等

      grepl("6", mtcars$disp)
      
       [1]  TRUE  TRUE FALSE FALSE  TRUE FALSE  TRUE  TRUE FALSE  TRUE  TRUE FALSE FALSE FALSE FALSE  TRUE FALSE
      [18] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
      
      mtcars$disp == "6"
      
      [1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
      [18] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-08-14
        • 2011-09-25
        • 2019-02-03
        • 1970-01-01
        相关资源
        最近更新 更多