R语言:如何判断DataFrame中的地址是否在另一DataFrame的地址区间内
地址区间匹配的最优解决方案
先给你构造可测试的示例数据,方便直接验证:
# 示例数据 df1 <- data.frame( Street_Name = c("Halley", "Main", "Halley", "Oak"), Street_Nr = c(25, 15, 18, 5) ) df2 <- data.frame( Street_Name = c("Halley", "Main"), Street_Starting_Nr = c(20, 10), Street_End_Nr = c(27, 20) )
方案一:用dplyr实现(易读且高效)
你之前尝试过dplyr,其实用left_join+条件判断就是最优的向量化方案,比for循环效率高太多:
library(dplyr) result <- df1 %>% # 按街道名称关联两个表 left_join(df2, by = "Street_Name") %>% # 判断编号是否在区间内,没匹配到街道的直接标记NO mutate( in_range = case_when( !is.na(Street_Starting_Nr) & Street_Nr >= Street_Starting_Nr & Street_Nr <= Street_End_Nr ~ "YES", TRUE ~ "NO" ) ) %>% # 保留需要的核心列 select(Street_Name, Street_Nr, in_range)
方案二:用data.table实现(性能更优,适合大数据量)
如果后续数据量更大,data.table的连接操作会更高效,语法也很紧凑:
library(data.table) # 转换为data.table格式 setDT(df1) setDT(df2) # 关联并标记区间匹配结果 result <- df1[df2, on = .(Street_Name), in_range := ifelse(Street_Nr >= Street_Starting_Nr & Street_Nr <= Street_End_Nr, "YES", "NO")] # 给没匹配到街道的地址补NO result[is.na(in_range), in_range := "NO"]
为什么这两个方案比for循环好?
- 都是向量化操作,避免了逐行循环的性能开销,7000行的规模几乎瞬间完成
- 代码简洁易读,后续维护修改更方便
- 完全覆盖所有场景:包括街道不在df2里的情况,会自动标记为NO
内容的提问来源于stack exchange,提问作者Elef Trax
相关产品推荐
相关产品推荐

