基于IUCR匹配为R语言DataFrame填充缺失的Primary.Type
高效填充DataFrame缺失值的解决方案
问题核心
你的需求是利用crime2021中完整的IUCR-Primary.Type映射,填充crime2020中Primary.Type的缺失值。嵌套循环的方法在20万行数据下完全不可行——时间复杂度为O(n*m),相当于40亿次操作,必然卡顿。
高效解决方案
推荐用dplyr(语法简洁)或data.table(性能最优,适合超大表)的连接操作实现,时间复杂度接近O(n+m),处理20万行数据秒级完成。
方法1:dplyr 实现
library(dplyr) # 1. 从crime2021提取唯一的IUCR-Primary.Type映射(避免重复IUCR导致连接后行数膨胀) iucr_mapping <- crime2021 %>% select(IUCR, Primary.Type) %>% distinct(IUCR, .keep_all = TRUE) # 按IUCR去重,保留对应Primary.Type # 2. 左连接+填充缺失值 crime2020_filled <- crime2020 %>% left_join(iucr_mapping, by = "IUCR", suffix = c("", "_2021")) %>% # 仅填充原Primary.Type为NA的行 mutate(Primary.Type = ifelse(is.na(Primary.Type), Primary.Type_2021, Primary.Type)) %>% # 移除临时列 select(-Primary.Type_2021)
方法2:data.table 实现(更适合大数据)
data.table的原地更新操作比dplyr更高效,内存占用也更低:
library(data.table) # 转换为data.table格式(不复制原数据,只是修改属性) setDT(crime2020) setDT(crime2021) # 1. 提取唯一映射 iucr_mapping <- unique(crime2021[, .(IUCR, Primary.Type)]) # 2. 按IUCR匹配,原地填充crime2020的缺失值 crime2020[iucr_mapping, on = .(IUCR), Primary.Type := ifelse(is.na(Primary.Type), i.Primary.Type, Primary.Type)]
关键注意事项
- 确保两个表的
IUCR列类型完全一致:如果一个是字符型(比如"0820"),一个是数值型(比如820),匹配会失败。可以用str_c()或as.character()统一转换为字符型。 - 必须先对crime2021的IUCR去重:如果crime2021中存在同一IUCR对应多个Primary.Type的情况(虽然你说一一对应,但实际数据可能有脏数据),去重后能避免连接后行数翻倍。
原代码问题说明
你的嵌套循环存在两个致命问题:
- 效率极低:20万×20万的循环次数完全超出R的处理能力;
- 逻辑错误:
ifelse的赋值写法不符合R的规范,内层循环的逻辑也会导致错误覆盖已填充的值。
内容的提问来源于stack exchange,提问作者Léo
相关产品推荐
相关产品推荐

