R:传递字符串向量以替换字符串中的所有实例
R: pass a vector of strings to replace all instances within a string
如果我有:
mystring<-"I have one cat, two dogs and three rabbits"
numlist<-c("one","two","three")
如何将 numlist
传递给 gsub
并替换 mystring
中匹配项的所有实例,以便我得到:
"I have ##NUMBER## cat, ##NUMBER## dogs and ##NUMBER## rabbits"
我试过:
> lapply(mystring,arg1=numlist,function(x,arg1) gsub(arg1,"##NUMBER##",x))
[[1]]
[1] "I have ##NUMBER## cat, two dogs and three rabbits"
Warning message:
In gsub(arg1, "##NUMBER##", x) :
argument 'pattern' has length > 1 and only the first element will be used
因为 gsub 没有向量化。但是我认为 lapply 可以解决这个问题?
您可以使用 lapply
、 或 您可以从搜索字符串构建正则表达式:
gsub(paste(numlist, collapse = '|'), '##NUMBER##', mystring)
这将匹配 numlist
中的任何字符串。
当使用 lapply
时,您需要反转参数,因为您希望将函数应用于 numlist
,而不是 mystring
;此外,您的函数必须只接受一个参数:
lapply(numlist, function (num) gsub(num, '##NUMBER##', mystring))
然而,这将产生不同的结果;即,它将 return 三个 结果字符串,每个字符串替换为不同的单词:
[[1]]
[1] "I have ##NUMBER## cat, two dogs and three rabbits"
[[2]]
[1] "I have one cat, ##NUMBER## dogs and three rabbits"
[[3]]
[1] "I have one cat, two dogs and ##NUMBER## rabbits"
需要用数字代替的话可以用gsubfn
library(gsubfn)
gsubfn("\w+", as.list(setNames(1:3, numlist)), mystring)
#[1] "I have 1 cat, 2 dogs and 3 rabbits"
编辑:我认为我们需要替换为与 'numlist' 中的单词相对应的数字。但是,如果我们需要用 ##NUMBER##
标志替换,一个选项是 mgsub
library(qdap)
mgsub(numlist, "##NUMBER##", mystring)
#[1] "I have ##NUMBER## cat, ##NUMBER## dogs and ##NUMBER## rabbits"
这不是一种优雅的方式,但它确实有效,
x <- "I have ##NUMBER## cat, ##NUMBER## dogs and ##NUMBER## rabbits"
numlist <- c("one","two","three")
for (i in 1:length(numlist)) {
loc <- regexpr("##NUMBER##", x)
start_loc <- loc[[1]]
width <- attr(loc, "match.length")
x <- paste(substr(x, 1, start_loc - 1), numlist[i], substr(x, start_loc + width, nchar(x)), sep = "")
}
输出:
> x
[1] "I have one cat, two dogs and three rabbits"
如果我有:
mystring<-"I have one cat, two dogs and three rabbits"
numlist<-c("one","two","three")
如何将 numlist
传递给 gsub
并替换 mystring
中匹配项的所有实例,以便我得到:
"I have ##NUMBER## cat, ##NUMBER## dogs and ##NUMBER## rabbits"
我试过:
> lapply(mystring,arg1=numlist,function(x,arg1) gsub(arg1,"##NUMBER##",x))
[[1]]
[1] "I have ##NUMBER## cat, two dogs and three rabbits"
Warning message:
In gsub(arg1, "##NUMBER##", x) :
argument 'pattern' has length > 1 and only the first element will be used
因为 gsub 没有向量化。但是我认为 lapply 可以解决这个问题?
您可以使用 lapply
、 或 您可以从搜索字符串构建正则表达式:
gsub(paste(numlist, collapse = '|'), '##NUMBER##', mystring)
这将匹配 numlist
中的任何字符串。
当使用 lapply
时,您需要反转参数,因为您希望将函数应用于 numlist
,而不是 mystring
;此外,您的函数必须只接受一个参数:
lapply(numlist, function (num) gsub(num, '##NUMBER##', mystring))
然而,这将产生不同的结果;即,它将 return 三个 结果字符串,每个字符串替换为不同的单词:
[[1]]
[1] "I have ##NUMBER## cat, two dogs and three rabbits"
[[2]]
[1] "I have one cat, ##NUMBER## dogs and three rabbits"
[[3]]
[1] "I have one cat, two dogs and ##NUMBER## rabbits"
需要用数字代替的话可以用gsubfn
library(gsubfn)
gsubfn("\w+", as.list(setNames(1:3, numlist)), mystring)
#[1] "I have 1 cat, 2 dogs and 3 rabbits"
编辑:我认为我们需要替换为与 'numlist' 中的单词相对应的数字。但是,如果我们需要用 ##NUMBER##
标志替换,一个选项是 mgsub
library(qdap)
mgsub(numlist, "##NUMBER##", mystring)
#[1] "I have ##NUMBER## cat, ##NUMBER## dogs and ##NUMBER## rabbits"
这不是一种优雅的方式,但它确实有效,
x <- "I have ##NUMBER## cat, ##NUMBER## dogs and ##NUMBER## rabbits"
numlist <- c("one","two","three")
for (i in 1:length(numlist)) {
loc <- regexpr("##NUMBER##", x)
start_loc <- loc[[1]]
width <- attr(loc, "match.length")
x <- paste(substr(x, 1, start_loc - 1), numlist[i], substr(x, start_loc + width, nchar(x)), sep = "")
}
输出:
> x
[1] "I have one cat, two dogs and three rabbits"