在R替换字符串模式和更换两个向量
比方说,我有两个向量像这样:在R替换字符串模式和更换两个向量
a <- c("this", "is", "test")
b <- c("that", "was", "boy")
我也有像这样一个字符串变量:
string <- "this is a story about a test"
我想替换值在字符串,以便它变成以下内容:
string <- "that was a story about a boy"
我可以使用for循环做到这一点,但我希望这是v ectorized。我应该怎么做?
如果你打开使用非基本包,stringi
真的会很好地工作在这里:
stringi::stri_replace_all_fixed(string, a, b, vectorize_all = FALSE)
#[1] "that was a story about a boy"
注意,这也以同样的方式对长度> 1
的输入字符串为了安全起见,可以适应这一点 - 类似于R用户的答案 - 更换前检查单词边界:
stri_replace_all_regex(string, paste0("\\b", a, "\\b"), b, vectorize_all = FALSE)
这将确保你不会意外例如,替换his
和hwas
。
> library(stringi)
> stri_replace_all_regex(string, "\\b" %s+% a %s+% "\\b", b, vectorize_all=FALSE)
#[1] "that was a story about a boy"
以下是一些解决方案。即使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)gsubfngsubfn
就像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)
做我们想要
- “一” 要与 “A”,然后回到 “A” 再次,或
- “A” 和 “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"
中以及切削用少许功能只依赖于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
定义分隔符。
说到外部包,这里的另一个问题:
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"
不错的一个! 'mgsub'可以让生活变得更容易,看起来好像是 – Sotos
如果'a
不错!我还没有接触过Reduce。非常感谢。 – hjms
已经添加了关于周期的注释 –
还有'regmatches(string,gregexpr(paste(a,collapse =“|”),string)) thelatemail