【问题标题】:Specify "ends with" in str_replace for fixing address abbreviations在 str_replace 中指定“以”结尾以修复地址缩写
【发布时间】:2021-12-07 03:35:50
【问题描述】:

我有多年的学校地址 df,但由于数据输入不一致,有些学校的地址在年份之间写得不同。

我正在尝试通过使用 str_replace 更改“St.”等内容来修复它们。进入“Street”,但有时我需要指定模式是字符向量的结尾。比如“West St”应该变成“West Street”,但是我把“St”换成“Street”,那么写对的就变成了“West Streetreet”。

test <- tribble(
  ~ name,   ~ year,   ~address,
  "school 1",  2000,   "1 Main Ave",
  "school 1",  2001,   "1 Main Avenue",
  "school 1",  2002,   "1 Main Ave",
  "school 1",  2004,   "1 Main Avenue",
  "school 2",  2000,   "200 West St",
  "school 2",  2001,   "200 West Street",
  "school 2",  2002,   "200 West St",
  "school 2",  2004,   "200 West St",
  "school 3",  2000,   "2759 Lakeshore Road",
  "school 3",  2001,   "2759 Lakeshore Road",
  "school 3",  2002,   "2759 Lakeshore Rd",
  "school 3",  2004,   "2759 Lakeshore Rd"

)

test %>% 
  mutate(address2 = str_replace(address, "Rd","Road"),
         address2 = str_replace(address2, "Ave","Avenue"),
         address2 = str_replace(address2, "St","Street"))
  

返回:

# A tibble: 12 × 4
   name      year address             address2           
   <chr>    <dbl> <chr>               <chr>              
 1 school 1  2000 1 Main Ave          1 Main Avenue      
 2 school 1  2001 1 Main Avenue       1 Main Avenuenue   
 3 school 1  2002 1 Main Ave          1 Main Avenue      
 4 school 1  2004 1 Main Avenue       1 Main Avenuenue   
 5 school 2  2000 200 West St         200 West Street    
 6 school 2  2001 200 West Street     200 West Streetreet
 7 school 2  2002 200 West St         200 West Street    
 8 school 2  2004 200 West St         200 West Street    
 9 school 3  2000 2759 Lakeshore Road 2759 Lakeshore Road
10 school 3  2001 2759 Lakeshore Road 2759 Lakeshore Road
11 school 3  2002 2759 Lakeshore Rd   2759 Lakeshore Road
12 school 3  2004 2759 Lakeshore Rd   2759 Lakeshore Road

这显然是不正确的。如何指定仅当模式以“St”结尾时才应更改?

【问题讨论】:

  • str_replace 函数从何而来?通常,您可以将正则表达式用于这样的任务,即"St$ 指定“St”必须位于 hte 行的末尾(在您的情况下输入)

标签: r regex dplyr stringr


【解决方案1】:

“$”表示字符串的结尾:

test %>% 
  mutate(address2 = str_replace(address, "Rd$","Road"),
         address2 = str_replace(address2, "Ave$","Avenue"),
         address2 = str_replace(address2, "St$","Street"))

【讨论】:

    【解决方案2】:

    您可以使用\\b 表示单词边界,因此St 可以出现在字符串中的任何位置,只有当它本身是一个完整的单词时才会被替换。

    library(dplyr)
    library(stringr)
    
    test %>% 
      mutate(address2 = str_replace(address, "\\bRd\\b","Road"),
             address2 = str_replace(address2, "\\bAve\\b","Avenue"),
             address2 = str_replace(address2, "\\bSt\\b","Street"))
    

    但是,如果您创建一个带有模式和替换的命名向量来查找这是一个带有str_replace_all 的单行 -

    pat <- setNames(c("Road", "Avenue", "Street"), 
                    c("\\bRd\\b", "\\bAve\\b", "\\bSt\\b"))
    
    test %>% mutate(address2 = str_replace_all(address, pat))
    
    #   name      year address             address2           
    #   <chr>    <dbl> <chr>               <chr>              
    # 1 school 1  2000 1 Main Ave          1 Main Avenue      
    # 2 school 1  2001 1 Main Avenue       1 Main Avenue      
    # 3 school 1  2002 1 Main Ave          1 Main Avenue      
    # 4 school 1  2004 1 Main Avenue       1 Main Avenue      
    # 5 school 2  2000 200 West St         200 West Street    
    # 6 school 2  2001 200 West Street     200 West Street    
    # 7 school 2  2002 200 West St         200 West Street    
    # 8 school 2  2004 200 West St         200 West Street    
    # 9 school 3  2000 2759 Lakeshore Road 2759 Lakeshore Road
    #10 school 3  2001 2759 Lakeshore Road 2759 Lakeshore Road
    #11 school 3  2002 2759 Lakeshore Rd   2759 Lakeshore Road
    #12 school 3  2004 2759 Lakeshore Rd   2759 Lakeshore Road
    

    【讨论】:

      【解决方案3】:

      您可以执行以下操作:这是因为您的数据具有特殊的组织: 首先创建组,然后将最长的字符串应用于所有组行,因为完整地址必须比缩写更长:

      library(dplyr)
      test %>% 
        group_by(name) %>% 
        mutate(address = address[which.max(str_length(address))]) %>% 
        ungroup()
      
      
         name      year address            
         <chr>    <dbl> <chr>              
       1 school 1  2000 1 Main Avenue      
       2 school 1  2002 1 Main Avenue      
       3 school 1  2001 1 Main Avenue      
       4 school 1  2004 1 Main Avenue      
       5 school 2  2000 200 West Street    
       6 school 2  2002 200 West Street    
       7 school 2  2004 200 West Street    
       8 school 2  2001 200 West Street    
       9 school 3  2002 2759 Lakeshore Road
      10 school 3  2004 2759 Lakeshore Road
      11 school 3  2000 2759 Lakeshore Road
      12 school 3  2001 2759 Lakeshore Road
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-04-25
        • 2013-02-01
        • 2012-04-01
        • 1970-01-01
        • 2015-07-17
        • 2017-02-05
        • 2021-08-28
        相关资源
        最近更新 更多