如何根据该列的值中是否存在字符串来替换该列中某些索引处的值(使用 dplyr 并在没有循环的情况下重复)?
How to replace values at certain indices in a column based on presence of a string in values of that column (using dplyr and repeatedly with no loop)?
使用 mtcars 的示例:
data(mtcars)
mtcars$car <- row.names (mtcars)
在汽车列中:我将汽车名称列为“Mazda RX4”、“Mazda RX4 Wag”、“Datsun 710”、“Hornet 4 Drive”等。假设我想删除汽车的型号和只留下制造商,例如“Mazda”、“Datsun”、“Hornet”,还 假设名称的格式不是始终将制造商作为第一个词,所以我也可以将汽车命名为“ModelX Mazda”或“model Tesla XX”,因此我无法将制造商提取为字符串的第一个单词。
如果您有一个包含所有制造商名称的字符串 c("Mazda", "Datsun", "Hornet"),您将如何完成这项任务?
如果有模式字符串,我们可以通过折叠 paste
来创建单个字符串
v1 <- c("Mazda", "Datsun", "Hornet")
pat <- paste0(".*\b(", paste(v1, collapse="|"), ")\b.*")
然后使用 sub
并将这些模式捕获为一组
mtcars$car[2] <- "RX4 Mazda Wag" # // changed for testing
out <- sub(pat, "\1", mtcars$car)
head(out, 5)
#[1] "Mazda" "Mazda" "Datsun" "Hornet" "Hornet"
或使用dplyr
library(dplyr)
library(stringr)
mtcars <- mtcars %>%
mutate(car = str_replace(car, pat, '\1'))
您也可以使用 str_extract
,如下所示:
vec <- c("Mazda", "Datsun", "Hornet")
str_extract(mtcars$car, str_c(v, collapse = '|'))
当然,如果您觉得给定汽车制造商的模型可能包含不同的汽车制造商,那么您应该用边界包裹图案。
即
str_extract(mtcars$car, sprintf("\b(%s)\b", str_c(v, collapse = '|')))
您可以使用 fuzzyjoin 包并执行 regex_left_join
to_match <- c("Mazda", "Datsun", "Hornet")
library(tidyverse)
df <-
mtcars %>%
rownames_to_column('car')
library(fuzzyjoin)
df %>%
regex_left_join(tibble(to_match), by = c('car' = 'to_match')) %>%
select(car, to_match) %>%
head
#> car to_match
#> 1 Mazda RX4 Mazda
#> 2 Mazda RX4 Wag Mazda
#> 3 Datsun 710 Datsun
#> 4 Hornet 4 Drive Hornet
#> 5 Hornet Sportabout Hornet
#> 6 Valiant <NA>
由 reprex package (v2.0.0)
于 2021-05-16 创建
使用 mtcars 的示例:
data(mtcars)
mtcars$car <- row.names (mtcars)
在汽车列中:我将汽车名称列为“Mazda RX4”、“Mazda RX4 Wag”、“Datsun 710”、“Hornet 4 Drive”等。假设我想删除汽车的型号和只留下制造商,例如“Mazda”、“Datsun”、“Hornet”,还 假设名称的格式不是始终将制造商作为第一个词,所以我也可以将汽车命名为“ModelX Mazda”或“model Tesla XX”,因此我无法将制造商提取为字符串的第一个单词。
如果您有一个包含所有制造商名称的字符串 c("Mazda", "Datsun", "Hornet"),您将如何完成这项任务?
如果有模式字符串,我们可以通过折叠 paste
v1 <- c("Mazda", "Datsun", "Hornet")
pat <- paste0(".*\b(", paste(v1, collapse="|"), ")\b.*")
然后使用 sub
并将这些模式捕获为一组
mtcars$car[2] <- "RX4 Mazda Wag" # // changed for testing
out <- sub(pat, "\1", mtcars$car)
head(out, 5)
#[1] "Mazda" "Mazda" "Datsun" "Hornet" "Hornet"
或使用dplyr
library(dplyr)
library(stringr)
mtcars <- mtcars %>%
mutate(car = str_replace(car, pat, '\1'))
您也可以使用 str_extract
,如下所示:
vec <- c("Mazda", "Datsun", "Hornet")
str_extract(mtcars$car, str_c(v, collapse = '|'))
当然,如果您觉得给定汽车制造商的模型可能包含不同的汽车制造商,那么您应该用边界包裹图案。 即
str_extract(mtcars$car, sprintf("\b(%s)\b", str_c(v, collapse = '|')))
您可以使用 fuzzyjoin 包并执行 regex_left_join
to_match <- c("Mazda", "Datsun", "Hornet")
library(tidyverse)
df <-
mtcars %>%
rownames_to_column('car')
library(fuzzyjoin)
df %>%
regex_left_join(tibble(to_match), by = c('car' = 'to_match')) %>%
select(car, to_match) %>%
head
#> car to_match
#> 1 Mazda RX4 Mazda
#> 2 Mazda RX4 Wag Mazda
#> 3 Datsun 710 Datsun
#> 4 Hornet 4 Drive Hornet
#> 5 Hornet Sportabout Hornet
#> 6 Valiant <NA>
由 reprex package (v2.0.0)
于 2021-05-16 创建