我们说我有两个这样的向量:
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循环执行此操作,但我希望将其进行矢量化。我该怎么做?
答案 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 gsubfn
与gsub
类似,但替换参数可以是替换列表(或某些其他对象)。
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)
我们想要
上面显示的所有解决方案都假设第一种情况。如果我们想要第二种情况,则执行两次操作。我们将用(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"