基于Tidyverse分批处理地址并迭代构建地理编码结果数据集的实现方案
基于Tidyverse分批处理地址并迭代构建地理编码结果数据集的实现方案
嘿,我懂你的需求啦——要处理海量地址(实际400万条),分批做地理编码,还要能实时跟踪批次进度,最后把所有结果整合到一个数据集里。你已经摸到了分组和循环的思路,但卡在了怎么不覆盖结果、逐步累积最终数据上,对吧?下面给你两种贴合Tidyverse风格的解决方案,都能满足你的需求:
首先先修正一个小问题:你的原始数据框里列名写的是sate(应该是state的笔误),先把这个修正过来,不然地理编码函数会找不到对应列:
df <- df %>% rename(state = sate)
方法一:用purrr实现无循环的分批处理(更贴合Tidyverse风格)
我们可以用group_split把数据按批次拆分,再用purrr::map_dfr自动处理每个批次并合并结果,同时加入批次进度打印:
library(tidyverse) library(tidygeocoder) # 给每条数据分配批次ID,每5条为一组(批次ID从0开始) df <- df %>% mutate(batch_id = (row_number() - 1) %/% 5) # 按批次拆分数据为列表 batch_list <- df %>% group_split(batch_id) # 分批地理编码并自动合并结果,同时打印进度 final_results <- map_dfr(batch_list, function(current_batch) { # 获取当前批次编号和总批次数 batch_num <- unique(current_batch$batch_id) + 1 total_batches <- length(batch_list) cat(paste("正在处理批次", batch_num, "/", total_batches, "\n")) # 对当前批次执行地理编码 current_batch %>% geocode( street = num_street, city = city, state = state, postalcode = zip_code, method = "census", full_results = TRUE, api_options = list(census_return_type = 'geographies') ) })
map_dfr会自动把每个批次的地理编码结果按行合并成一个完整的数据框,不用手动处理列表合并,非常省心。
方法二:改进你的循环代码,实现结果累积
如果你更习惯用循环,只要用一个列表来存储每个批次的结果,最后再合并就行,这样就不会覆盖之前的结果了:
library(tidyverse) library(tidygeocoder) # 给每条数据分配批次ID df <- df %>% mutate(batch_id = (row_number() - 1) %/% 5) # 初始化一个空列表,用来存储每个批次的结果 results_list <- list() total_batches <- max(df$batch_id) + 1 for (x in 0:max(df$batch_id)) { cat(paste("\r正在处理批次", x + 1, "of", total_batches, "\n")) Sys.sleep(1) # 可选,避免请求过于频繁触发API限流 # 筛选当前批次的数据 current_batch <- df %>% filter(batch_id == x) # 执行地理编码 geocoded_batch <- current_batch %>% geocode( street = num_street, city = city, state = state, postalcode = zip_code, method = "census", full_results = TRUE, api_options = list(census_return_type = 'geographies') ) # 将当前批次结果添加到列表中 results_list[[x + 1]] <- geocoded_batch } # 合并所有批次的结果为一个数据框 final_results <- bind_rows(results_list)
额外小贴士
处理400万条数据时,要注意API的请求限制:
- 可以根据API的限流规则调整批次大小(不一定是5条,可能可以调大)
- 适当延长
Sys.sleep的时间,避免被API暂时封禁 - 如果想进一步提速,可以考虑用
furrr包实现并行处理批次,但要注意不要超过API的并发请求限制
备注:内容来源于stack exchange,提问作者C.Robin
相关产品推荐
相关产品推荐

