R:为什么循环或c()不能用于grep函数?

时间:2015-04-27 13:52:55

标签: r grep

感谢grep using a character vector with multiple patterns,我也想出了自己的问题。 这里的问题是如何使用grep函数找到多个值, 解决方案是这两个:

grep("A1| A9 | A6") 

toMatch <- c("A1", "A9", "A6")
matches <- unique (grep(paste(toMatch,collapse="|")

所以我使用了第二个建议,因为我有很多值要搜索。

但我很好奇为什么c()或for循环不能用而不是|。 在我研究stackoverflow中的可能解决方案并找到上述建议之前,我尝试了两种替代方案,我将在下面演示:

首先,我在R中写的是这样的:

find.explore.l<-lapply(text.words.bl ,function(m) grep("^explor",m))

但是我不得不'grep'很多单词,所以我尝试了这个

find.explore.l<-lapply(text.words.bl ,function(m) grep(c("A1","A2","A3"),m))

它不起作用,所以我尝试了另一个(XXX是我应该在文本中找到的单词列表)

for (i in XXX){
  find.explore.l<-lapply(text.words.bl ,function(m) grep("XXX[i]"),m))
    .......(more lines to append lines etc)
   }

似乎R试图匹配XXX [i]本身,而不是里面的单词。 为什么c()和for循环for grep不能返回正确的结果? 有人请让我知道!我很好奇:P

2 个答案:

答案 0 :(得分:1)

来自pattern=函数中grep()参数的文档:

  

包含要在给定字符向量中匹配的正则表达式(或fixed = TRUE的字符串)的字符串。如果可能,由as.character强制转换为字符串。 如果提供长度为2或更长的字符向量,则第一个元素将使用警告。除regexprgregexpr外,允许缺少值。

这证实,正如@nrussell在评论中所说,grep()没有在模式参数上进行矢量化。因此,c()不适用于正则表达式列表。

可以,但是,使用循环,你只需要修改你的语法。

toMatch <- c("A1", "A9", "A6")

# Loop over values to match
for (i in toMatch) {
    grep(i, text)
}

使用"XXX[i]"作为您的模式并不起作用,因为它将其解释为正则表达式。也就是说,它将完全匹配XXXi。要引用正则表达式向量的元素,只需使用XXX[i](注意缺少周围的引号)。

你可以apply()这个,但方式与你做的略有不同。您将它应用于列表中的每个 regex ,而不是每个文本字符串。

lapply(toMatch, function(rgx, text) grep(rgx, text), text = text)

然而,正如您在帖子中所使用的那样,最好的方法是使用

matches <- unique(grep(paste(toMatch, collapse = "|"), text))

答案 1 :(得分:0)

考虑一下:

XXX <- c("a", "b", "XXX[i]")
grep("XXX[i]", XXX, value=T)
character(0)
grep("XXX\\[i\\]", XXX, value=T)
[1] "XXX[i]"

R在做什么?它对grep的第一个参数使用特殊规则。括号被视为特殊字符([])。我输入两个反斜杠告诉R将它们视为常规括号。并且如果我将最后一个表达式放入for循环中会发生什么?它不会按我的预期行事。

如果您希望for循环遍历可能匹配的字符向量,请取出grep函数中的引号。

#if you want the match returned
matches <- c("a", "b")
for (i in matches) print(grep(i, XXX, value=T))
[1] "a"
[1] "b"

#if you want the vector location of the match
for (i in matches) print(grep(i, XXX))
[1] 1
[1] 2

正如评论所指出的那样,grep(c("A1","A2","A3"),m))违反了grep所需的语法。