在R语言中基于列内地址范围生成含单个地址的新行
地址范围拆分扩展为单独地址的解决方案
原始数据
data <- data.frame("Street" = c("Example1", "Example2", "Example3", "Example4"), "Number" = c("10-20a", "4b-8", NA, "14-16"))
对应的原始数据框:
Street Number 1 Example1 10-20a 2 Example2 4b-8 3 Example3 <NA> 4 Example4 14-16
需求
将上述数据中的地址范围拆分,生成包含每个单独地址的数据框,目标格式如下:
data_long <- data.frame("Street" = c(rep("Example1", 11), rep("Example2", 5), "Example3", rep("Example4", 3)), "Number" = c(10:19,"20a", "4b", 5:8, NA, c(14:16)))
对应的数据框:
Street Number 1 Example1 10 2 Example1 11 3 Example1 12 4 Example1 13 5 Example1 14 6 Example1 15 7 Example1 16 8 Example1 17 9 Example1 18 10 Example1 19 11 Example1 20a 12 Example2 4b 13 Example2 5 14 Example2 6 15 Example2 7 16 Example2 8 17 Example3 <NA> 18 Example4 14 19 Example4 15 20 Example4 16
问题背景
尝试过拆分数字与字母,结合rowwise()和mutate()处理,但失败了——字母会被错误附加到每个地址上。
解决方案
使用tidyverse工具集处理,核心思路是拆分地址范围的起始/结束项,区分数字部分和字母后缀,再针对性生成单独地址序列:
library(tidyverse) data %>% # 拆分地址范围为起始、结束两部分,NA项保持不变 mutate(Number = ifelse(is.na(Number), NA, str_split(Number, "-", simplify = TRUE))) %>% unnest_wider(Number, names_sep = "_") %>% rename(start = Number_1, end = Number_2) %>% # 提取起始/结束项的数字和字母后缀 mutate( start_num = as.integer(str_extract(start, "\\d+")), start_suffix = str_extract(start, "[a-zA-Z]+"), end_num = as.integer(str_extract(end, "\\d+")), end_suffix = str_extract(end, "[a-zA-Z]+"), # 处理无结束项的情况(如纯单个地址) end_num = ifelse(is.na(end_num), start_num, end_num) ) %>% rowwise() %>% # 生成单独地址列表:带后缀的起始项单独保留,中间数字序列转字符,带后缀的结束项单独保留 mutate( Number_list = list( c( if (!is.na(start_suffix)) start, if (start_num < end_num) as.character(start_num:end_num), if (!is.na(end_suffix)) end ) ) ) %>% # 处理NA地址的情况 mutate(Number_list = ifelse(is.na(start), list(NA), Number_list)) %>% # 展开列表为多行 unnest(Number_list) %>% # 整理列名 select(Street, Number = Number_list)
代码说明
- 拆分地址范围:用
str_split把带-的地址拆成起始和结束两部分,NA项直接保留 - 提取数字与后缀:用正则表达式分离出每个项的数字部分和字母后缀,方便后续区分处理
- 生成地址序列:
- 如果起始项带字母(如
4b),直接保留该地址 - 起始数字小于结束数字时,生成中间的数字序列并转为字符
- 如果结束项带字母(如
20a),最后保留该地址
- 如果起始项带字母(如
- 展开多行:将生成的地址列表展开为单独行,匹配对应的街道名称
运行后即可得到符合需求的长格式数据框。
内容的提问来源于stack exchange,提问作者anon
相关产品推荐
相关产品推荐

