0

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

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"

我要做的是查找例如单词oneoron是否在文本中,然后将新值分配给one新变量d。此外,如果层次结构中有多个值,a则应来自最后一个值。

我能做的是以下几点:

d <- list()
d[grepl(b[1],c)] <- a[1]
d[grepl(b[2],c)] <- a[2]
d[grepl(b[3],c)] <- a[3]
d <- unlist(d)

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

4

1 回答 1

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 循环更实用的解决方案,因为它避免了重复分配。另一方面,它似乎有点复杂。

顺便说一句:我在任何地方都使用了a,bc,以便更容易地将我的代码与您的示例相匹配。然而,这不是好的被认为是好的做法。

于 2015-11-19T19:49:40.977 回答