Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
184 views
in Technique[技术] by (71.8m points)

Batch Geocoding with googleway R

I'm having trouble using the google_geocode function in the googleway package to batch geocode. I'd like to input a data frame of addresses and have the latitude and longitude coordinates returned for each. The number of addresses is far beyond Google's 2,500 daily query limit, so the solution needs to use an API key to allow the purchase of more queries.

## Your Google API key
key<-"<insert key here>"
###  Make Data Frame with two observations
Dt<-as.data.frame(matrix(c(" 4605 Langdon ST , Fernley , NV , 89408", -119.2026,
          " 350 Quivera LN , Sparks , NV , 89441", NA), ncol=2)) 
###Change Column Names
colnames(Dt)<-c("address", "longitude")

### Make address column character
Dt$address<-as.character(Dt$address)

### Make data frame with one observation
dt<-Dt[1,]


### geocode one observation with googleway  This Works!!
google_geocode(address = dt[,"address"],
           key = key)  

### batch geocode 
res <- apply(Dt, 1, function(Dt){

google_geocode(address=list(Dt[,"address"]),
              key = key)
})

##  Error in Dt[, "address"] : incorrect number of dimensions
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The way you've constructed your data.frame seems a bit convoluted, so I'm re-doing it here

dt <- data.frame(address = c("4605 Langdon St, Fernley, NV, 89408", 
                             "350 Quivera Ln, Sparks, NV, 89441"),
                 stringsAsFactors = FALSE)

Then you can use an *apply method to geocode each one

library(googleway)

key <- 'api_key'

res <- apply(dt, 1, function(x){
  google_geocode(address = x[['address']],
                 key = key)
})

str(res)
# List of 2
# $ :List of 2
# ..$ results:'data.frame': 1 obs. of  5 variables:
#   .. ..$ address_components:List of 1
# .. .. ..$ :'data.frame':  8 obs. of  3 variables:
#   .. .. .. ..$ long_name : chr [1:8] "4605" "Langdon Street" "Fernley" "Lyon County" ...
# .. .. .. ..$ short_name: chr [1:8] "4605" "Langdon St" "Fernley" "Lyon County" ...
# .. .. .. ..$ types     :List of 8
# .. .. .. .. ..$ : chr "street_number"
# .. .. .. .. ..$ : chr "route"
# ... etc

You can then extract the coordinates for each result and do whatever you want with it...

coords <- lapply(res, function(x){
  x$results$geometry$location
})

coords <- lapply(seq_along(res), function(x){
  coords <- res[[x]]$results$geometry$location
  address <- dt[x, 'address']
  res_df <- data.frame(lat = coords[, 'lat'],
                       lon = coords[, 'lng'], 
                       address = address
                       )
})

df_coords <- do.call(rbind, coords)
df_coords
#        lat       lon                             address
# 1 39.59275 -119.2026 4605 Langdon St, Fernley, NV, 89408
# 2 39.68911 -119.6345   350 Quivera Ln, Sparks, NV, 89441

mapKey <- symbolix.utils::mapKey()

google_map(key = mapKey) %>%
  add_markers(data = df_coords, lat = "lat", lon = "lon", info_window = "address")

enter image description here


Notes:

If you wanted to be 'sure' that the coordinates lined up with the input addresses, you should construct your results inside the *apply that does the geocoding.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...