R语言如何基于城市名与人口为数据集添加对应国家名称列
R语言大型数据集批量匹配城市所属国家的实现方案
针对十万到百万级以上的大型数据集,核心原则是避免逐行判断,用标准化的表关联逻辑做匹配,速度快、内存占用低,后续维护映射规则也方便。
前期准备
首先准备两份数据:
- 你的原始城市数据集:注意提前把
population字段从带逗号的字符串转成数值型,方便后续做重名校验,转换参考代码:# 把"500,000"这类带逗号的字符串转成数值500000 your_df$population <- as.numeric(gsub(",", "", your_df$population)) - 城市-国家映射基准表:至少包含
city(城市名)、country(对应国家)两个字段,如果存在同名城市,加上population字段做精准匹配。
不想手动整理全量映射的话,可以直接用maps包内置的全球城市数据集当基础库,覆盖绝大多数主流城市:
内置库没覆盖的小众城市,手动补到映射表里就行,一劳永逸。library(maps) data(world.cities) # 提取需要的字段整理成标准映射表 city_map <- data.frame( city = world.cities$name, population = world.cities$pop, country = world.cities$country.etc )
大表最优匹配方案(优先选)
用data.table做关联匹配,是目前R语言里处理GB级大表速度最快、内存开销最小的方案,比基础R的匹配逻辑快几十倍,比常规tidyverse方案快3-10倍。
library(data.table) # 把原始数据和映射表都转成data.table格式(用fread读入的数据默认就是这个格式,不用重复转换) setDT(your_df) setDT(city_map) # 单字段匹配(无重名城市场景) your_df[city_map, on = .(city), country := i.country] # 城市+人口双字段精准匹配(有重名城市场景,匹配准确率更高) # your_df[city_map, on = .(city, population), country := i.country]
运行完直接在原始表上新增country列,没有多余的内存拷贝,大表下跑起来基本秒出结果。
可读性优先方案
如果你更习惯tidyverse的代码风格,千万行级以内的表用dplyr的左连接也完全够用:
library(dplyr) result_df <- your_df %>% # 单字段匹配就写by = "city" left_join(city_map, by = c("city", "population"))
大表避坑提示
- 别用
case_when、ifelse逐行硬写城市和国家的对应关系,城市量超过100个之后代码会极难维护,匹配速度会断崖式下跌,大表下容易卡崩。 - 匹配前统一清洗城市名字段:用
trimws()去掉首尾空格、统一大小写、替换特殊字符,避免因为"Oslo "(末尾带空格)和"Oslo"格式不一致导致匹配失败。 - 匹配完之后用
sum(is.na(your_df$country))统计未匹配成功的行数,把这部分城市补到映射表之后重跑即可,不用全量重复计算。 - 大文件读写优先用
data.table的fread()/fwrite(),比基础的read.csv()、write.csv()快10倍以上,内存占用低一半以上。
内容的提问来源于stack exchange,提问作者user18723720
相关产品推荐
相关产品推荐

