解决地理编码场景中R代码出现的‘object 'd' not found’错误
解决Nominatim OSM地理编码R函数中的"object 'd' not found"错误
我帮你排查了问题,核心原因是nominatim_osm函数里的tryCatch写法有问题,另外还有两个小细节会影响API请求的成功率:
问题分析
tryCatch的变量作用域问题:
你原来的代码是在tryCatch的表达式里给d赋值,如果API请求或JSON解析触发错误,这个赋值操作根本不会完成,d变量就不存在。但函数后续还会执行if(length(d) == 0),自然会抛出object 'd' not found的错误。URL参数格式错误:
请求URL里用了HTML实体&,这应该换成普通的&,否则Nominatim API无法正确识别参数。地址编码不完整:
仅替换空格为%20不足以处理非ASCII字符(比如你最后一个俄语地址),需要用URLencode做完整的URL编码,避免请求被API拒绝。
修复后的完整代码
library(dplyr) library(jsonlite) nominatim_osm <- function(address = NULL) { if(suppressWarnings(is.null(address))) return(data.frame()) # 对地址做完整的URL编码,处理所有特殊字符 encoded_addr <- URLencode(address, reserved = TRUE) # 修复URL参数分隔符,用&代替&,并把tryCatch的结果赋值给d d <- tryCatch( jsonlite::fromJSON( sprintf('http://nominatim.openstreetmap.org/search/%s?format=json&addressdetails=0&limit=1', encoded_addr) ), error = function(c) return(data.frame()) ) # 现在d一定存在,判断是否为空 if(length(d) == 0) return(data.frame(lon = NA, lat = NA)) return(data.frame(lon = as.numeric(d$lon), lat = as.numeric(d$lat))) } addresses <- c("Baker Street 221b, London", "Brandenburger Tor, Berlin", "Platz der Deutschen Einheit 1, Hamburg", "Arc de Triomphe de l’Etoile, Paris", "Дворцовая пл., Санкт-Петербург, Россия") d <- suppressWarnings(lapply(addresses, function(address) { t <- Sys.time() api_output <- nominatim_osm(address) t <- difftime(Sys.time(), t, units = 'secs') return(data.frame(address = address, api_output, elapsed_time = t)) }) %>% bind_rows() %>% data.frame()) # 输出结果 print(d, row.names = FALSE)
修复说明
- 把
tryCatch的结果直接赋值给d,无论请求成功还是失败,d都会有值,避免了未定义变量的错误。 - 用
URLencode处理地址,确保所有特殊字符(包括非ASCII字符)都符合URL规范。 - 修正了URL中的参数分隔符,让API能正确解析请求参数。
- 当API返回空结果时,返回包含
NA的经纬度,这样结果数据框的结构保持一致,不会出现列缺失的情况。
运行修复后的代码,你会得到包含地址、经纬度和耗时的完整结果,不会再遇到object 'd' not found的错误。
内容的提问来源于stack exchange,提问作者topfdergier
相关产品推荐
相关产品推荐

