2016-05-12 63 views
1

內更換所有實例如果我有:R:通過一個字符串矢量爲字符串

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 

因爲... e gsub不是矢量化的。但是我認爲lapply可以照顧這個?

回答

2

我們可以使用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" 
+1

我相信如果你運行基準測試,mgsub是迄今爲止最快的解決方案。 –

+1

謝謝 - 這對我有用。 – brucezepplin

2

您可以使用lapply您可以從您的搜索字符串構造正則表達式:

gsub(paste(numlist, collapse = '|'), '##NUMBER##', mystring) 

這將匹配在numlist任何字符串。

當使用lapply時,您需要顛倒您的參數,因爲您要將該功能應用於numlist而不是mystring;此外,您的功能必須採用一個參數:

lapply(numlist, function (num) gsub(num, '##NUMBER##', mystring)) 

但是,這會產生不同的結果;即,它將返回結果串,每一個不同的字代替:

[[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" 
+0

而更換好,我真的必須只有一個結果返回。 – brucezepplin

0

不是一個優雅的方式,但它的作品,

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"