Tidyverse:基于部分匹配替换整个字符串
我希望使用Tidyverse:基于部分匹配替换整个字符串,r,tidyverse,stringr,R,Tidyverse,Stringr,我希望使用stringr包中的函数替换基于部分匹配的数据中的整个字符串条目 我尝试过的唯一方法是使用str\u replace\u all()替换精确匹配,但当有几十种变体需要纠正时,这种方法会变得乏味和笨拙。我正在寻找基于部分匹配的替换。在我下面的reprex中,我用直接规范替换了“西班牙人”和“哥伦比亚人”的变体。然而,我希望在满足单词中存在“Spa”或“Col”的条件的基础上执行这些替换 库(tidyverse) 图书馆(stringr) 数据[1]“西班牙人”“西班牙人”“西班牙人”“哥
stringr
包中的函数替换基于部分匹配的数据中的整个字符串条目
我尝试过的唯一方法是使用str\u replace\u all()
替换精确匹配,但当有几十种变体需要纠正时,这种方法会变得乏味和笨拙。我正在寻找基于部分匹配的替换。在我下面的reprex中,我用直接规范替换了“西班牙人”和“哥伦比亚人”的变体。然而,我希望在满足单词中存在“Spa”或“Col”的条件的基础上执行这些替换
库(tidyverse)
图书馆(stringr)
数据[1]“西班牙人”“西班牙人”“西班牙人”“哥伦比亚人”“哥伦比亚人”
#>[6]“厄瓜多尔”“厄瓜多尔”“厄瓜多尔”“委内瑞拉”
由(v0.2.1)于2019年5月21日创建
因此,
str\u replace\u all()
就像广告宣传的那样工作,但我正在寻找一种在tidyverse中简化此过程的方法。非常感谢您的帮助。可以选择使用距离法进行部分匹配
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"
我更喜欢使用距离度量(例如,Jaro winkler距离,或其他一些距离度量),但它们确实有缺点。对部分匹配可能带来的变化感到厌倦。如果您正在进行部分匹配,那么明智的做法是查看可能性。但是,当使用
startsWith
或grepl
启动时,您可以使用case\u执行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
我刚刚了解到距离度量概念的存在。关于如何在R中应用它的任何建议?嘿@ChrisAguilar,我将从stringdist
的文档开始,在RecordLinkage
中也有一些距离度量。我没有太多的评论,除了他们引用的报纸/维基百科,我已经看过了。对不起,我不是更多的帮助,而是祝你好运!!!因此,只需创建一个具有所需值的字符向量,并如上所述应用amatch()
,即可应用更正。太好了!这种方法是否有缺点,或者在失败时是否有常见的例子?谢谢。@ChrisAguilar是的。它基于距离法,因此如果匹配元素变化过大,则可能必须增加maxDist
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))