【问题标题】:Extract House Number from (address) string using r使用 r 从(地址)字符串中提取门牌号
【发布时间】:2015-05-06 10:50:33
【问题描述】:

我想将地址解析(提取)成 HouseNumber 和 Streetname。 稍后我应该能够将提取的“值”写入新列(shops$HouseNumber 和 stores$Streetname)。

假设我有一个名为“商店”的数据框:

> shops
      Name                 city        street
 1    Something            Fakecity    New Street 3
 2    SomethingOther       Fakecity    Some-Complicated-Casestreet 1-3
 3    SomethingDifferent   Fakecity    Fake Street 14a

那么有没有办法将街道列分成两个列表,一个是街道名称,一个是门牌号码,包括“1-3”、“14a”等情况,这样最后就可以分配结果到数据框,看起来像。

 > shops
      Name                 city        Streetname                    HouseNumber
 1    Something            Fakecity    New Street                    3
 2    SomethingOther       Fakecity    Some-Complicated-Casestreet   1-3
 3    SomethingDifferent   Fakecity    Fake Street                   14a 

示例:Easyfakestreet 5 --> Easyfakestreet , 5

由于我的一些街道字符串将具有连字符的街道地址并且具有非数字组件,因此它变得有些复杂。

示例:
New Street 3 --> ['New Street', '3']
Some-Complicated-Casestreet 1-3 --> ['Some-Complicated-Casestreet','1-3']
假街 14a --> ['假街', '14a']

我将不胜感激!

【问题讨论】:

    标签: r split street-address


    【解决方案1】:

    这是一个可能的tidyr 解决方案

    library(tidyr)
    extract(df, "street", c("Streetname", "HouseNumber"), "(\\D+)(\\d.*)")
    #                 Name     city                   Streetname HouseNumber
    # 1          Something Fakecity                  New Street            3
    # 2     SomethingOther Fakecity Some-Complicated-Casestreet          1-3
    # 3 SomethingDifferent Fakecity                 Fake Street          14a
    

    【讨论】:

    • 非常感谢!这适用于我所有的案例,即使是我之前没有识别的案例,比如街道名称和门牌号之间缺少空格。
    【解决方案2】:

    你可以试试:

    shops$Streetname <- gsub("(.+)\\s[^ ]+$","\\1", shops$street)
    shops$HousNumber <- gsub(".+\\s([^ ]+)$","\\1", shops$street)
    

    数据

    shops$street
    #[1] "New Street 3"                    "Some-Complicated-Casestreet 1-3" "Fake Street 14a" 
    

    结果

    shops$Streetname
    #[1] "New Street"                  "Some-Complicated-Casestreet" "Fake` Street" 
    
    shops$HousNumber
    #[1] "3"   "1-3" "14a"
    

    【讨论】:

    • 谢谢!那效果很好。但我发现它不适用于我自己之前没有识别的一个案例,其中格式错误“Fake Street48”(缺少空格)。
    • @Deset,确实,如果缺少空间,imy regex 将无法工作
    【解决方案3】:

    使用匹配街道和号码的反向引用创建一个模式,然后使用sub 依次将其替换为每个反向引用。不需要任何软件包:

    pat <- "(.*) (\\d.*)"
    transform(shops,
       street = sub(pat, "\\1", street), 
       HouseNumber = sub(pat, "\\2", street)
    )
    

    给予:

                    Name     city                      street  HouseNumber
    1          Something Fakecity                  New Street            3
    2     SomethingOther Fakecity Some-Complicated-Casestreet          1-3
    3 SomethingDifferent Fakecity                 Fake Street          14a
    

    这是pat的可视化:

    (.*) (\d.*)
    

    Debuggex Demo

    注意:

    1) 我们将其用于shops

    shops <-
    structure(list(Name = c("Something", "SomethingOther", "SomethingDifferent"
    ), city = c("Fakecity", "Fakecity", "Fakecity"), street = c("New Street 3", 
    "Some-Complicated-Casestreet 1-3", "Fake Street 14a")), .Names = c("Name", 
    "city", "street"), class = "data.frame", row.names = c(NA, -3L))
    

    2) David Arenburg 的模式可以在这里交替使用。只需将pat 设置为它。上面的模式的优点是它允许在其中嵌入数字的街道名称,但 David 的优点是街道号之前可能会缺少空格。

    【讨论】:

      【解决方案4】:

      你可以使用包脱胶

      library(unglue)
      unglue_unnest(shops, street, "{street} {value=\\d.*}")
      #>                 Name     city                      street value
      #> 1          Something Fakecity                  New Street     3
      #> 2     SomethingOther Fakecity Some-Complicated-Casestreet   1-3
      #> 3 SomethingDifferent Fakecity                 Fake Street   14a
      

      reprex package (v0.3.0) 于 2019 年 10 月 8 日创建

      【讨论】:

        【解决方案5】:

        国际地址的非常复杂的问题

        $re = '/(\d+[\d\/\-\. ,]*[ ,\d\-\w]{0,2} )/m';
        $str = '234 Test Road, Testville
        456b Tester Road, Testville
        789 c Tester Road, Testville
        Mystreet 14a 
        123/3 dsdsdfs
        Roobertinkatu 36-40 
        Flats 1-24 Acacia Avenue 
        Apartment 9D, 1 Acacia Avenue 
        Flat 24, 1 Acacia Avenue
        Moscow Street, plot,23 building 2 
        Apartment 5005  no. 7 lane 31 Wuming Rd
        Quinta da Redonda Lote 3 - 1 º 
        102 - 3 Esq 
        Av 1 Maio 16,2 dt,
        Rua de Ceuta Lote 1 Loja 5 
        11334 Nc Highway 72 E ';
        
        preg_match_all($re, $str, $matches, PREG_SET_ORDER, 0);
        
        // Print the entire match result
        var_dump($matches);
        

        Output example

        https://regex101.com/r/WVPBji/1

        【讨论】:

          猜你喜欢
          • 2020-04-11
          • 2018-12-03
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-11-22
          • 2012-12-14
          相关资源
          最近更新 更多