Reputation: 148
How can I use purrr::map()
to return the result of the for loop of the example:
vct_string <- c("old ccar","new carr", "house", "oold house")
df_correction <- data.frame(
pattern = c("ccar", "carr", "oold"),
replacement = c("car", "car", "old"),
stringsAsFactors = FALSE
)
for(i in 1:nrow(df_correction)){
vct_string <- pmap(df_correction, gsub, x = vct_string)[[i]]
}
> vct_string
[1] "old car" "new car" "house" "old house"
Upvotes: 3
Views: 147
Reputation: 79198
Actually, you do not need any of the ReduceMap
functions. Just use str_replace_all
its vectorized
library(stringr)
str_replace_all(vct_string, set_names(df_correction$replacement, df_correction$pattern))
[1] "old car" "new car" "house" "old house"
Upvotes: 4
Reputation: 26218
You have to recursively modify your vector so in my opinion this is classic case of usage of reduce family function here. So do this, where you will have to pass your vector to .init
argument of purrr::reduce
to get the desired output
purrr::reduce(seq(nrow(df_correction)), .init = vct_string, ~ gsub(df_correction$pattern[.y], df_correction$replacement[.y], .x))
#> [1] "old car" "new car" "house" "old house"
This will even do multiple replacements in elements of given vector. see this
#modified example
vct_string <- c("old ccar","new carr", "house", "oold carr")
purrr::reduce(seq(nrow(df_correction)), .init = vct_string, ~ gsub(df_correction$pattern[.y], df_correction$replacement[.y], .x))
[1] "old car" "new car" "house" "old car"
Upvotes: 3
Reputation: 21908
Here is how you could do it with base::Reduce:
Reduce(function(x, y) {
gsub(df_correction[y, 1], df_correction[y, 2], x)
}, init = vct_string, 1:nrow(df_correction))
[1] "old car" "new car" "house" "old house"
Upvotes: 1
Reputation: 1969
First write a function for the replacements
word_correct <- function(string) {
df_correction <- data.frame(
pattern = c("old ccar", " new carr", "oold house", "house"), # changed from OP
replacement = c("car", "car", "old", "house"),
stringsAsFactors = FALSE
)
df_correction[ which(df_correction$pattern == string), "replacement"]
}
# Testing
word_correct("oold")
word_correct("ccar")
Then you can pass that function as an argument in purrr::map
map_chr(vct_string, word_correct) # using map_chr to return a vector instead of a list which is what map returns
Since you are using a mapping table to replace individual words, you can actually use map
in a second function to get your desired results.
vct_string <- c("old ccar","new carr", "house", "oold house")
single_word_correct <- function(string) {
df_correction <- data.frame(
pattern = c("ccar", "carr", "oold"),
replacement = c("car", "car", "old"),
stringsAsFactors = FALSE
)
if(string %in% df_correction$pattern){
df_correction[ which(df_correction$pattern == string), "replacement"]
} else {
string
}
}
multi_word_correct <- function(string){
strings <- strsplit(string, " ")[[1]]
paste(map_chr(strings, single_word_correct), collapse = " ")
}
map_chr(vct_string, multi_word_correct)
Upvotes: 1