1

I've written a function that will pull geospatial data from the Google Maps API and store the 1) name 2) coordinates in a dataframe using the googleway function 'google_places'.

Google_places uses a "next page token" for a total of 3 API calls for one full search.

When pulled out of the function, this code runs perfectly and returns a 60 row dataframe.

However, when I run this function using the appropriate arguments, it returns a dataframe of only 40 results.

I have been explicit in my code to run all three calls necessary, not just two.

I am not sure why this code works outside the function, but not inside the function.

Does anyone know what is happening here?

Again, this is using the googleway google_places function. https://rdrr.io/cran/googleway/man/google_places.html

Thank you! This is the code:

i. First set the conditions used in the search

search_string <- "Urgent care center"
key <- key #my API key
radius <- 50000
location <- L1 


#L1 is a numeric vector of coordinates [1]   39 -105


search <- google_places(search_string, key, location, radius)

ii. Function to initialize the search by creating the dataframe from one search call (there are three total search calls).

thin_df <- function(search){
  a <- search$results$name
  b <- search$results$geometry$location$lat
  c <- search$results$geometry$location$lng
  thin_df <- data.frame(a, b, c)
  return(thin_df)}

iii. In this function a 'central df' combines the three 'thin df' call results, creating a full search for the first coordinate pair using the arguments previously defined and the thin_df function.

full_search <- function(search_string, 
       key, location, radius){

call_1 <- google_places(search_string, 
                        key, 
                        location, 
                        radius)
thin1 <- thin_df(call_1)

call_2 <- google_places(search_string = search_string, 
                      page_token = call_1$next_page_token, 
                      key = key, 
                      location = location, 
                      radius = radius)
thin2 <- thin_df(call_2)
full_df <- rbind(thin1, thin2)

call_3 <- google_places(search_string, 
                      page_token = call_2$next_page_token,
                      key, 
                      location, 
                      radius)
thin3 <- thin_df(call_3)
central_df <- rbind(full_df, thin3)
return(central_df)
}
  
central_df <- full_search(("Urgent care center", key, L1, 50000)
SymbolixAU
  • 25,502
  • 4
  • 67
  • 139
  • Please include the code you have tried in the question instead of an image. – Vishal A. Feb 16 '22 at 06:34
  • Hi Vishal - thank you, I've updated the post – Parker Novak Feb 18 '22 at 19:30
  • as per your [other question](https://stackoverflow.com/a/71190339/5977215) this line is wrong `google_places(search_string, key, location, radius)`. You should explicitely state which argument is which. – SymbolixAU Feb 20 '22 at 01:33
  • does my answer solve your issue? – SymbolixAU Feb 27 '22 at 07:47
  • Yes, this is excellent. I noticed that developers Cooley and Barcelos at SymbolixAU developed googleway. How do I go about citing this correctly in my code, and any support I received here on Stack Overflow? – Parker Novak Feb 28 '22 at 22:33
  • 1
    The typical way to cite something is using the `citation()` function - e.g. `citation("googleway")` – SymbolixAU Feb 28 '22 at 23:08

1 Answers1

2

I suspect your issue is you are violating the number of requests you can make per second.

In my example here

  • I use a while loop to control multiple calls
  • I've added a Sys.sleep(2) call to suspend the function for 2 seconds
  • I use access_results to get the specific components of the result (this is just a convenience function)
  • I check the status of the result res$status and only try and get the contents if it's "OK"

This is just something I put together to give you some ideas on how to get it working and handle some common errors. Feel free to change it to suit your programming style / requirements.

search_string <- "Urgent care center"
key <- secret::get_secret("GOOGLE")
radius <- 50000
location <- c(39, -105)

format_res <- function(res) {

  setNames(
    cbind(
      googleway::access_result(res, "coordinates")
      , googleway::access_result(res, "place_name")
    )
    , c("lat", "long", "name")
  )
}

do_search <- function(search_string, key, location, radius, page_token = NULL) {
  
  google_places(
    search_string = search_string
    , location = location
    , key = key
    , radius = radius
    , page_token = page_token
  )
}

full_search <- function(search_string, key, location, radius) {
  
  counter <- 0
  
  page_token <- NULL ## can start on NULL because it means we're doing the first query
  is_another_page <- TRUE 
  
   
  while( is_another_page ) {
    
    res <- do_search(search_string, key, location, radius, page_token)
    
    if( res$status == "OK" ) { ## check a valid result was returned
    
      if( counter == 0 ) {
        df <- format_res( res )
      } else {
        df <- rbind(df, format_res( res ) )
      }
      
      counter <- counter + 1
    }
    
    page_token <- res[["next_page_token"]]
    is_another_page <- !is.null( page_token )
    Sys.sleep(2)  ## Sleep the function before the next call because there's a time limit
  }
  return(df)
}

df <- full_search(search_string, key, location, radius)

str( df )
# 'data.frame': 60 obs. of  3 variables:
#   $ lat : num  38.9 38.8 38.9 38.9 38.9 ...
# $ long: num  -105 -105 -105 -105 -105 ...
# $ name: chr  "UCHealth Urgent Care - Garden of the Gods" "UCHealth Urgent Care - Circle Square" "Penrose Community Urgent Care" "Emergicare Austin Bluffs" ...

SymbolixAU
  • 25,502
  • 4
  • 67
  • 139
  • How can I build a full search for `google_places()` with search_string only? A simple search? – Marco Jan 02 '23 at 14:49