Tidyverse:根据部分匹配替换整个字符串

时间:2019-05-21 14:49:04

标签: r tidyverse stringr

我希望使用stringr包中的函数根据部分匹配替换数据中的整个字符串条目。

我尝试过的唯一方法是使用str_replace_all()替换完全匹配项,但是当有数十种要纠正的变体时,这变得乏味且笨拙。我希望根据部分匹配项进行替换。在下面的reprex中,我直接指定了“西班牙人”和“哥伦比亚人”的变体。但是,我希望根据满足单词中“ Spa”或“ Col”的条件进行替换。

library(tidyverse)
library(stringr)

data <- c(
  "Spanish",
  "SPANIARD",
  "Spainiard",
  "Colombian",
  "Columbian",
  "Ecuador",
  "Equador",
  "Ecuadorian",
  "VENEZUELAN"
)

str_replace_all(data,
                c(
                  "Spanish" = "Spaniard",
                  "SPANIARD" = "Spaniard",
                  "Spainiard" = "Spaniard",
                  "Columbian" = "Colombian"
                ))
#> [1] "Spaniard"   "Spaniard"   "Spaniard"   "Colombian"  "Colombian" 
#> [6] "Ecuador"    "Equador"    "Ecuadorian" "VENEZUELAN"

reprex package(v0.2.1)于2019-05-21创建

因此str_replace_all()的工作方式与广告宣传相符,但我正在寻找一种方法来简化tidyverse中的此过程。非常感谢您的帮助。

2 个答案:

答案 0 :(得分:1)

一种选择是使用距离法进行部分匹配

vals <- c("Spaniard", "Equador", "Colombian", "Venezuelan")
library(stringdist)
vals[amatch(tolower(data), tolower(vals),maxDist=5)]
#[1] "Spaniard"   "Spaniard"   "Spaniard"   "Colombian"  "Colombian"  
#[6] "Equador"    "Equador"    "Equador"    "Venezuelan"

它可以通过tidyverse工作流程进行管道传输

library(tidyverse)
tibble(v1 = data) %>%
    mutate(v1 = vals[amatch(tolower(v1), tolower(vals), maxDist = 5)])

答案 1 :(得分:1)

我更喜欢使用距离度量(例如Jaro-winkler的距离或其他某种距离度量),但是它们确实有其缺点。厌倦了部分匹配可能会带来的变化。如果您要进行部分匹配,那么明智的做法是看看有什么可能。但是,您可以将case_whenstartsWithgrepl一起在tidyverse中进行概述:

tibble(data = data) %>%
  mutate(
    v1 = tolower(data),
    new_name = case_when(
      startsWith(v1, "spa") ~ "Spanaird",
      startsWith(v1, "col") ~ "Colombian",
      startsWith(v1, "eq") | startsWith(v1, "ec") ~ "Equadorian",
      startsWith(v1, "ven") ~ "Venezuelan",
      TRUE ~ as.character(data)))

# A tibble: 9 x 3
  data       v1         new_name  
  <chr>      <chr>      <chr>     
1 Spanish    spanish    Spanaird  
2 SPANIARD   spaniard   Spanaird  
3 Spainiard  spainiard  Spanaird  
4 Colombian  colombian  Colombian 
5 Columbian  columbian  Colombian 
6 Ecuador    ecuador    Equadorian
7 Equador    equador    Equadorian
8 Ecuadorian ecuadorian Equadorian
9 VENEZUELAN venezuelan Venezuelan

要查看可能的方法,您可以执行此操作(或其他一些操作):

tibble(data = data) %>%
  arrange(data) %>%
  count(tolower(data))