使用googleway在R中进行地理编码

问题描述 投票:1回答:2

我读过Batch Geocoding with googleway R

我试图使用googleway对一些地址进行地理编码。我想要返回地理编码,地址和县。

使用上面链接的答案我创建了以下功能。

geocodes<-lapply(seq_along(res),function(x) {
  coordinates<-res[[x]]$results$geometry$location
  df<-as.data.frame(unlist(res[[x]]$results$address_components))
  address<-paste(df[1,],df[2,],sep = " ")
  city<-paste0(df[3,])
  county<-paste0(df[4,])
  state<-paste0(df[5,])
  zip<-paste0(df[7,])
  coordinates<-cbind(coordinates,address,city,county,state,zip)
  coordinates<-as.data.frame(coordinates)
})

然后把它放回原处......

library(data.table)

done<-rbindlist(geocodes))

问题是让地址和县从“res”列表中退出。上面链接的答案从发送到谷歌的数据框中提取地址,并假设列表的顺序正确,谷歌没有多个匹配结果(在我的列表中似乎有一对)。点是,从一个文件中获取地址,而另一个文件的坐标看起来相当鲁莽,因为无论如何我需要该县,我需要一种方法将它从谷歌的结果列表中保存在'res'中。

问题是某些地址比其他地址有更多的“类型”,这意味着按行进行引用,因为我上面做的不起作用。

我还尝试在函数中包含rbindlist,将子列表转换为数据表,然后拉出字段,但不能让它工作。这种方法的问题是实际地址在向量中,但我将用于过滤或选择的“类型”字段位于子列表中。

我可以描述它的最佳方式是这样 - 列表< - c(长地址),c(短地址),类型(LIST(街道号,路线,县等))

显然,我是初学者。我知道有一种更简单的方法,但我只是真的在与列表挣扎,R似乎广泛使用它们。

编辑:我绝对认识到我不能整个列表。我需要将特定元素拉出来并仅绑定那些元素。在我看来,问题的很大一部分是我没有很好的处理索引和操作列表。

以下是一些可以尝试的地址 - “301 Adams St,Friendship,WI 53934,USA”有一个7X3“地址组件”和相应的“类型”列表7.比较“222 S Walnut St,Appleton,WI 45911,USA “其地址组件为9X3,”类型“列表为9.类型列表需要连接回地址组件矩阵,因为类型列表标识了地址组件矩阵的每一行包含的内容。

然后由不完美的匹配引入更多复杂性。尝试“211 Grand Avenue,Rothschild,WI,54474”,你会得到2个名单,一个是东部大街,另一个是西部大街。谷歌似乎更喜欢东方,因为这是“格式化地址”中出现的内容。我真的不在乎使用哪个,因为这两个县都是一样的。有趣地,“位置”包含2组地理编码,可能是指两个匹配。我认为这种复杂性可以忽略,因为由两个坐标组成的位置仍然存储为“双”(不是列表!),因此它应该与其他地址的坐标堆叠。

编辑:这应该真的有效,但我在函数的do.call(rbind,types)行中出错。

geocodes<-lapply(seq_along(res),function(x) {
  coordinates<-res[[x]]$results$geometry$location
  types<-res[[x]]$results$address_components[[1]]$types
  types<-do.call(rbind,types)
  types<-types[,1]
  address<-as.data.frame(res[[x]]$results$address_components[[1]]$long_name,strings.As.Factors=FALSE)
  names(address)[1]<-"V2"
  address<-cbind(address,types)
  address<-tidyr::spread(address,types,V2)
  address<-cbind(address,coordinates)
})

R表示“类型”对象不是列表,因此无法对其进行处理。我尝试将其强制转移到列表但仍然得到错误。我使用下面的配对向下功能检查,发现#294为空。这会停止功能。我得到“超过查询限制”作为错误,但我没有超过查询限制。

geocodes<-lapply(seq_along(res),function(x) {
  types<-res[[x]]$results$address_components[[1]]$types
  print(typeof(types))
})
r list geocoding nested-lists googleway
2个回答
1
投票

这是我使用tidyverse函数的解决方案。这将获取地理编码以及格式化的地址(如果需要)(结果的其他组件也可以返回,它们只需要添加到返回的map函数的最后一行中的表中。

suppressPackageStartupMessages(require(tidyverse))
suppressPackageStartupMessages(require(googleway))

set_key("your key here")

df <- tibble(full_address = c("2379 ADDISON BLVD HIGH POINT 27262", 
                                      "1751 W LEXINGTON AVE HIGH POINT 27262", "dljknbkjs"))

df %>% 
  mutate(geocode_result = map(full_address, function(full_address) {
    res <- google_geocode(full_address) 

    if(res$status == "OK") {

      geo <- geocode_coordinates(res) %>% as_tibble()

      formatted_address <- geocode_address(res)

      geocode <- bind_cols(geo, formatted_address = formatted_address)
    }
    else geocode <- tibble(lat = NA, lng = NA, formatted_address = NA)

    return(geocode)

  })) %>%
  unnest()
#> # A tibble: 3 x 4
#>   full_address                  lat   lng formatted_address                
#>   <chr>                       <dbl> <dbl> <chr>                            
#> 1 2379 ADDISON BLVD HIGH POI…  36.0 -80.0 2379 Addison Blvd, High Point, N…
#> 2 1751 W LEXINGTON AVE HIGH …  36.0 -80.1 1751 W Lexington Ave, High Point…
#> 3 dljknbkjs                    NA    NA   <NA>

reprex package创建于2019-04-14(v0.2.1)


0
投票

好的,我会自己回答。

从地址数据框开始。我称之为“地址”,数据帧中的单数列也称为“地址”(注意我将其大写)。

使用googleway获取地理编码数据。我使用apply来循环遍历地址数据帧中的行

library(googleway)

    res<-apply(addresses,1,function (x){
      google_geocode(address=x[['Address']], key='insert your google api key here - its free to get')  
    })

这是我编写的用于将嵌套列表放入数据帧的函数。

geocodes<-lapply(seq_along(res),function(x) {
  coordinates<-res[[x]]$results$geometry$location
  types<-res[[x]]$results$address_components[[1]]$types
  types<-do.call(rbind,types)
  types<-types[,1]
  address<-as.data.frame(res[[x]]$results$address_components[[1]]$long_name,strings.As.Factors=FALSE)
  names(address)[1]<-"V2"
  address<-cbind(address,types)
  address<-tidyr::spread(address,types,V2)
  address<-cbind(address,coordinates)
  })

library(data.table)
geocodes<-rbindlist(geocodes,fill=TRUE)

lapply沿着列表中的项循环,在函数中我创建坐标数据框并将地理编码放在那里。我还想要其他地址组件,特别是县,所以我还创建了“类型”数据框,用于标识地址中的项目。我用类型来处理地址项,然后使用tidyr包中的spread来将数据帧重新整形为宽格式,因此它只有1行宽。然后我从坐标数据帧中的lat和lb中进行cbind。

rbindlist将它们全部堆叠在一起。你可以使用do.call(rbind, geocodes),但rbindlist更快。

© www.soinside.com 2019 - 2024. All rights reserved.