如何将df$addr列拆分为df$str.num与df$str.name列?处理连字符场景
解决方案:拆分含连字符的地址为街道编号与名称
嘿,这个问题我处理类似数据时也碰到过!核心难点就是那些带连字符的内容(比如84-86、380-2)其实是街道编号的一部分,不能直接按空格或连字符粗暴拆分。咱们用正则表达式就能精准匹配出开头的编号部分,剩下的自然就是街道名称了。
先看你的示例数据:
addr <- c("84-86 19th Ave", "35 Halsey St", "350 Broad St", "997 S Orange Ave", "274 Chestnut St", "226 Lackawanna Ave", "99 2nd Ave", "261 S Orange Ave", "357 Wilson Ave", "402 Mount Prospect Ave # Lb2", "380-2 Mount Prospect Ave", "105 Lock St # 219", "451 S 15th St") df <- data.frame(addr)
方案一:用tidyverse工具链(推荐,代码更直观)
先加载tidyverse包,然后用str_extract提取编号,str_remove剥离编号得到街道名称:
library(tidyverse) df <- df %>% mutate( # 提取开头的数字(可选带连字符+数字)作为街道编号 str.num = str_extract(addr, "^\\d+(-\\d+)?") %>% trimws(), # 移除开头的编号+空格,剩下的就是街道名称 str.name = str_remove(addr, "^\\d+(-\\d+)?\\s") %>% trimws() )
方案二:用Base R(无需额外安装包)
如果不想加载额外包,用Base R的正则函数也能实现:
# 提取街道编号 df$str.num <- trimws(regmatches(df$addr, regexpr("^\\d+(-\\d+)?", df$addr))) # 生成街道名称 df$str.name <- trimws(sub("^\\d+(-\\d+)?\\s", "", df$addr))
正则表达式说明
这里用到的^\\d+(-\\d+)?是关键:
^:匹配字符串开头\\d+:匹配一个或多个数字(-\\d+)?:可选匹配一个连字符加一个或多个数字(括号里的?表示这部分是可选的,完美适配带/不带连字符的编号)
最终效果
运行代码后,你的df会新增两列,结果如下:
addr str.num str.name 1 84-86 19th Ave 84-86 19th Ave 2 35 Halsey St 35 Halsey St 3 350 Broad St 350 Broad St 4 997 S Orange Ave 997 S Orange Ave 5 274 Chestnut St 274 Chestnut St 6 226 Lackawanna Ave 226 Lackawanna Ave 7 99 2nd Ave 99 2nd Ave 8 261 S Orange Ave 261 S Orange Ave 9 357 Wilson Ave 357 Wilson Ave 10 402 Mount Prospect Ave # Lb2 402 Mount Prospect Ave # Lb2 11 380-2 Mount Prospect Ave 380-2 Mount Prospect Ave 12 105 Lock St # 219 105 Lock St # 219 13 451 S 15th St 451 S 15th St
如果后续遇到其他特殊格式的地址(比如编号后带字母),只需要微调正则表达式就能适配啦!
内容的提问来源于stack exchange,提问作者GaryM
相关产品推荐
相关产品推荐

