用模式替换R中的字符串并替换两个向量

时间:2017-07-25 10:53:36

标签: r string vector

我们说我有两个这样的向量:

a <- c("this", "is", "test")
b <- c("that", "was", "boy")

我也有一个像这样的字符串变量:

string <- "this is a story about a test"

我想替换string中的值,使其成为以下内容:

string <- "that was a story about a boy"

我可以使用for循环执行此操作,但我希望将其进行矢量化。我该怎么做?

5 个答案:

答案 0 :(得分:8)

如果您愿意使用非基础软件包,stringi在这里可以正常使用:

stringi::stri_replace_all_fixed(string, a, b, vectorize_all = FALSE)
#[1] "that was a story about a boy"

请注意,对于长度为&gt;的输入字符串,这也是一样的。 1。

为安全起见,您可以根据RUser的答案进行调整 - 在更换之前检查字边界:

stri_replace_all_regex(string, paste0("\\b", a, "\\b"), b, vectorize_all = FALSE)

这样可以确保您不会意外地将his替换为hwas,例如。

答案 1 :(得分:4)

以下是一些解决方案。即使string是字符串的字符向量,它们也都可以工作,在这种情况下,将对其中的每个组件进行替换。

1)减少这不使用任何包。

Reduce(function(x, i) gsub(paste0("\\b", a[i], "\\b"), b[i], x), seq_along(a), string)
## [1] "that was a story about a boy"

2)gsubfn gsubfngsub类似,但替换参数可以是替换列表(或某些其他对象)。

library(gsubfn)

gsubfn("\\w+", setNames(as.list(b), a), string)
## [1] "that was a story about a boy"

3)循环这不是矢量化的,但已添加用于比较。没有包使用。

out <- string
for(i in seq_along(a)) out <- gsub(paste0("\\b", a[i], "\\b"), b[i], out)
out
## [1] "that was a story about a boy"

注意:有一些问题是循环是否可行。例如,如果

a <- c("a", "A")
b <- rev(a)

我们想要

  • &#34;&#34;将被替换为&#34; A&#34;然后回到&#34; a&#34;再次,或
  • &#34;&#34;和&#34; A&#34;被交换。

上面显示的所有解决方案都假设第一种情况。如果我们想要第二种情况,则执行两次操作。我们将用(2)说明,因为它是最短的,但同样的想法适用于它们:

# swap "a" and "A"
a <- c("a", "A")
b <- rev(a)

tmp <- gsubfn("\\w+", setNames(as.list(seq_along(a)), a), string)
gsubfn("\\w+", setNames(as.list(b), seq_along(a)), tmp)
## [1] "this is A story about A test"

答案 2 :(得分:3)

> library(stringi)
> stri_replace_all_regex(string, "\\b" %s+% a %s+% "\\b", b, vectorize_all=FALSE)
#[1] "that was a story about a boy"

答案 3 :(得分:2)

还有一个只依赖于R base的小功能:

repWords <- function(string,toRep,Rep,sep='\\s'){

  wrds <- unlist(strsplit(string,sep))
  ix <- match(toRep,wrds)
  wrds[ix] <- Rep  
  return(paste0(wrds,collapse = ' '))

}

a <- c("this", "is", "test")
b <- c("that", "was", "boy")

string <- "this is a story about a test"

> repWords(string,a,b)
[1] "that was a story about a boy"

注意:

这假设您有匹配的替换次数。您可以使用sep定义分隔符。

答案 4 :(得分:2)

谈论外部包装,这是另一个:

a <- c("this", "is", "test")
b <- c("that", "was", "boy")
x <- "this is a story about a test"


library(qdap)
mgsub(a,b,x)

给出:

 "that was a story about a boy"