使用grepl进行多页文本

时间:2015-11-19 18:24:54

标签: r grep

让我们假设我有以下变量:

a <- c('one','two','three')
b <- c('one|on','two|wo',"three|thre")
c <- c('there is one','there one is ','there is one three two')

我想要一个具有以下结果的新变量:

 d
 [1] "one"   "one"   "three"

我要做的是查找文本中是否有单词oneon,然后为新变量{{1}分配新值one }}。此外,如果d中有多个值,则层次结构应该来自最后一个值。

我能做的是以下几点:

a

同样可以在一个简单的循环中完成。但还有其他方式更优雅吗?

1 个答案:

答案 0 :(得分:0)

它并不是那么优雅,但是这个功能可以满足您的需求:

funny_replace <- function(c, b, a) {

   max_or_null <- function(x) {
      if (length(x) != 0) max(x) else NULL
   }

   multi_grep <- function(b, x) {
      which(sapply(b, grepl, x))
   }

   replace_one <- function(s, b, a) {
      a[max_or_null(multi_grep(b, s))]
   }

   unlist(sapply(c, replace_one, b, a)) 
}
funny_replace(c, b, a)
#      there is one          there one is  there is one three two 
#             "one"                  "one"                "three" 

它的工作原理如下:max_or_null用于返回向量的最大值,如果向量为空则返回NULL。稍后会使用此选项来确保正确处理c中未匹配b的模式的元素。

multi_grep在单个字符串中搜索多个模式(通常grep执行相反的操作:多个字符串中的一个模式)并返回找到的模式的索引。

replace_one只需一个字符串并检查,使用b找到multi_grep中的哪些模式。然后使用max_or_null返回这些索引中最大的索引,如果没有匹配则返回NULL。最后,从a中选择具有此索引的元素。

然后将

replace_one应用于c的每个元素以获得所需的结果。

我认为,它比你的或者for循环更具功能性,因为它避免了重复分配。另一方面,它看起来有点复杂。

顺便说一句:我在任何地方都使用了abc,以便更轻松地将我的代码与您的示例相匹配。但是,这不是一个好的做法。