在R中进行反向地理编码的循环

11

我正在尝试对一个大型数据集(约10万条)进行反向地理编码。我使用了来自 ggmap 软件包的 revgeocode 函数。我已经获得了1个条目的结果。

48 Grand View Terrace, San Francisco, 
CA 94114, USA            
48 Grand View Terrace Eureka Valley San Francisco        
San Francisco County                  California United States
postal_code postal_code_suffix

但我需要自动化这个过程,并将其用于整个数据集。

我尝试过

r <- lapply(revgeocode(location = (c(z$lon),c(z$lat)),
             output = "more",
            messaging = FALSE, sensor = FALSE, override_limit = FALSE,
            client = "", signature = ""))

并且在每一步中都遇到了意外的','错误。

我也尝试编写了以下循环:

r <- for(i in 1:10){
  revgeocode(location = ("z$lon", "z$lat"),output = "more", messaging =      FALSE, sensor = FALSE, override_limit = FALSE,client = "", signature = "")}

并且收到了类似的错误。

请提供一些材料或有用的链接,帮助我编写反向地理编码循环。如何验证数据的真实性?


1
Google Maps API 每天的查询限制为 2500 次。因此,您可能希望采取一些措施来考虑这一点。 - Rick Arko
@RickArko 是的,我知道这个事实!有没有办法使用这个 ggmap 代码调用API?我想每1000个查询需要支付0.5美元。 - marine8115
2个回答

8
根据这个答案, 你可以在你的数据框中创建新变量。
我们使用 mapply() 处理你的坐标并将结果返回到列表 res 中。
res <- mapply(FUN = function(lon, lat) { 
  revgeocode(c(lon, lat), output = "more") 
  }, 
  df$lon, df$lat
  )

然后,我们使用data.table中的rbindlist()将列表转换为data.frame(使用fill = TRUE,因为res的所有元素长度不相同,即某些结果没有返回street_numberpostal_code),并将其与原始数据cbind()
cbind(df, data.table::rbindlist(res, fill = TRUE))

更新

回复您的评论,如果您想处理超过2500个查询,您可以订阅Google Maps API高级版以解锁更高的配额。然后,您可以使用signatureclient参数将您的凭据传递给revgeocode()

文档所述:

购买Google Maps API高级版许可证后,您将收到一封来自Google的欢迎电子邮件,其中包含您的客户端ID和私有加密密钥。

您的客户端ID用于访问Google Maps API高级版的特殊功能。所有客户端ID都以gme-前缀开头。将您的客户端ID作为客户端参数的值传递。使用您的私有加密密钥生成唯一的数字签名。将此签名作为签名参数的值传递。

你可以通过检查revgeocode()源代码来了解它是如何在后台运作的,同时可以查看URL的构造方式:
sensor4url <- paste("&sensor=", sensor, sep = "")
client4url <- paste("&client=", client, sep = "")
signature4url <- paste("&signature=", signature, sep = "")
url_string <- paste("http://maps.googleapis.com/maps/api/geocode/json?latlng=", 
        loc4url, sensor4url, sep = "")
    if (userType == "business") {
        url_string <- paste(url_string, client4url, signature4url, 
            sep = "")
    }

数据

df <- structure(list(lat = c(32.31, 32.19, 34.75, 35.09, 35.35, 34.74 ), lon = 
c(119.827, 119.637, 119.381, 119.364, 119.534, 119.421 )), .Names = 
c("lat", "lon"), row.names = c(21L, 32L, 37L, 48L, 50L, 89L), class = "data.frame") 

我已经按照你提供的示例尝试了一下,它完美地运行了!谢谢你的帮助!但是,我该如何将大型数据集转换为你所规定的格式?我遇到了错误 Error: is.numeric(location) && length(location) == 2 is not TRUE。我尝试通过 lst <-list(ll4$lontat) 创建列表,其中ll4是我的数据集名称,lonlat对应一个包含(119.08,39.24)这样的条目的列。谢谢! - marine8115
@AmitR.Pathak 请提供 dput(head(ll4)) - Steven Beaupré
结构(列表)(纬度= c(32.31, 32.19, 34.75, 35.09, 35.35, 34.74),经度= c(119.827,119.637,119.381,119.364,119.534,119.421)),名称= c(“纬度”,“经度”),行名= c(21L,32L,37L,48L,50L,89L),类别=“数据框”) - marine8115
有没有通过调用API并支付反向地理编码的方式来完成它的方法。我需要尽快完成。 - marine8115
我已经在Google讨论论坛上发布了帖子,但没有收到答复。同时,我已经订阅了Google Cloud平台的免费试用,并获得了300美元进行实验。我稍微编辑了一下代码,并设置了“override_limit = TRUE”。这使我可以处理超过每天2500个查询,但您是否知道计费将如何处理?我运行了500个额外的样本,超过了2500个,但没有收到来自Google的付款电子邮件。我无法获得高级计划,因为它仅适用于企业。 - marine8115
显示剩余2条评论

0

我曾经遇到过一个类似的问题,就是集成API密钥的问题。基本上,这是一个将API密钥集成到R调用的URL中的问题。 如果这个不能帮助你,你需要改变核心代码(在Github上查找),以允许调用密钥的参数。


getGeoData <- function(latlng, api_key){ geo_data <- getURL(paste("https://maps.googleapis.com/maps/api/geocode/json?","latlng=",latlng,"&key=",sep="")) geo_data <- fromJSON(geo_data) return(geo_data$results[[1]])}根据帖子的建议,我编写了一个反向地理编码函数。我还尝试应用以下循环,以便可以处理多个查询 for (i in 1:10) { geo_data[i] = getGeoData(unique(y1[i,4]))} 。我收到错误消息number of items to replace is not a multiple of replacement length。有什么建议来解决这个问题吗? - marine8115
我是一名R语言的新手,但应该写成geo_data[[i]]才对吧?我现在工作很忙,但我很快会去看一下。 - pdx

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接