zl程序教程

您现在的位置是:首页 >  工具

当前栏目

讨论学习R的grepl函数

学习 函数 讨论
2023-06-13 09:13:01 时间

废话不多说,我们来聊聊今天的正题。昨天有位群友在群里提出了这样一个问题

具体的字符串向量是这样的,需要达到的目的就是,看字符串向量里面的每一个元素是否包含"LIPE2"这个基因。这里的字符串向量有四个元素。

实现的手段就是通过R的grepl函数

这个函数里的pattern是匹配的模式,也就是我们经常听到的正则表达式。如果对正则表达式还不了解的小伙伴,可以参考☞正则表达式☜x就是要查看是否满足pattern的字符串向量,如果匹配pattern就返回TRUE,不满足就返回FASLE。

这位群友所提出的问题,tricky的地方在于LIPE2这个基因有时候存在于字符串的中间,有时候存在于开头,有时候又存在于末尾,并且还需要考虑一些干扰项比如LIPE23这个基因也能够匹配LIPE2,似乎很难通过一个正则表达式来实现。后来这位群友自己解决了这个问题,方法就是通过来实现。既然一个正则表达式无法满足需要,那就多写几个正则表达式,把所有可能的情况都考虑进去。

这个问题引起了群里关于正则表达式激烈的讨论,

其实,在这个群友提出这个问题之前,我还不太确定,pattern里面可以使用或(|),通过讨论大家都有所收获,至少群里的其他小伙伴知道了正则表达式这个概念。以后遇到相似的问题,也知道怎么解决了。

今天我又仔细的研究了一下,给出了三种实现的方法,供大家交流学习。我又加入了一个干扰项,让这个正则表达式更全面。

s <- c("ABCLIPE2", #LIPE2前面有干扰
       "LIPE-AS1,LIPE,CXCL17",
       "LIPE-AS1,LIPE2,LIPE,CXCL17", #LIPE2在中间,前后都有,
       "LIPE2",  #LIPE2在字符串的开始,或者结尾
       "LIPE23")  #LIPE2后面有干扰

方法一,直接匹配所有可能的情况

#^LIPE2$:匹配整个字符串只有LIPE2这个基因,^锚定开始,$锚定结尾
#,LIPE2,:匹配LIPE2在中间,前后都有其他基因
#^LIPE2,:匹配LIPE2在开始,后面有基因
#,LIPE2$:匹配LIPE2在结尾,前面有基因
#|是或,即满足其中任何一个条件即可
grepl("^LIPE2$|,LIPE2,|^LIPE2,|,LIPE2$",s)
#[1] FALSE FALSE  TRUE  TRUE FALSE

方法二,利用\b,单词边界

#\b匹配一个单词边界,也就是指单词和空格间的位置。
#例如,“er\b”可以匹配“never”中的“er”,但不能匹配“verb”中的“er”。
grepl("\\bLIPE2\\b",s)
#[1] FALSE FALSE  TRUE  TRUE FALSE

方法三,利用strsplit和%in%

sapply(s,function(x){
  'LIPE2' %in% strsplit(x,',')[[1]]
})

返回的结果是

如果对strsplit还不熟悉的小伙伴,其实可以先输出来看看结果

sapply(s,function(x){
  strsplit(x,',')[[1]]
})

返回的结果是分割之后的字符串向量

参考资料:

  1. 正则表达式
  2. https://www.rdocumentation.org/packages/base/versions/3.6.2/topics/strsplit
  3. https://www.rdocumentation.org/packages/base/versions/3.6.2/topics/grep