1

I have a list of ambiguous addresses that I need to return full geocode information for.

  • Only issue is that what I get is a large list of nested lists (JSON)
  • I want to be able to get a data frame that contains the key information, i.e.
  • IDEAL OUTPUT
  • Original_Address, StreetNum, StreetName, Suburb, town_city, locality, Postcode, geo_xCord, Country, Postcode

I almost wonder if this is just too difficult and if there is an easier method that I haven't considered. I basically just need to be able to spit out the key address elements for each address I have.

# Stack Overflow Example -------------------------------------------
random_addresses <- c('27 Hall Street, Wellington',
                      '52 Ethan Street, New Zealand',
                      '13 Epsom Street, Auckland',
                      '42 Elden Drive, New Zealand')


register_google(key = "MYAPIKEY") 
place_lookup <- geocode(random_addresses, output = "all")

print(place_lookup[1]) 


>>>


[[1]]$results
[[1]]$results[[1]]
[[1]]$results[[1]]$address_components
[[1]]$results[[1]]$address_components[[1]]
[[1]]$results[[1]]$address_components[[1]]$long_name
[1] "27"

[[1]]$results[[1]]$address_components[[1]]$short_name
[1] "27"

[[1]]$results[[1]]$address_components[[1]]$types
[[1]]$results[[1]]$address_components[[1]]$types[[1]]
[1] "street_number"



[[1]]$results[[1]]$address_components[[2]]
[[1]]$results[[1]]$address_components[[2]]$long_name
[1] "Hall Street"

[[1]]$results[[1]]$address_components[[2]]$short_name
[1] "Hall St"

[[1]]$results[[1]]$address_components[[2]]$types
[[1]]$results[[1]]$address_components[[2]]$types[[1]]
[1] "route"



[[1]]$results[[1]]$address_components[[3]]
[[1]]$results[[1]]$address_components[[3]]$long_name
[1] "Newtown"

[[1]]$results[[1]]$address_components[[3]]$short_name
[1] "Newtown"

[[1]]$results[[1]]$address_components[[3]]$types
[[1]]$results[[1]]$address_components[[3]]$types[[1]]
[1] "political"

[[1]]$results[[1]]$address_components[[3]]$types[[2]]
[1] "sublocality"

[[1]]$results[[1]]$address_components[[3]]$types[[3]]
[1] "sublocality_level_1"



[[1]]$results[[1]]$address_components[[4]]
[[1]]$results[[1]]$address_components[[4]]$long_name
[1] "Wellington"

[[1]]$results[[1]]$address_components[[4]]$short_name
[1] "Wellington"

[[1]]$results[[1]]$address_components[[4]]$types
[[1]]$results[[1]]$address_components[[4]]$types[[1]]
[1] "locality"

[[1]]$results[[1]]$address_components[[4]]$types[[2]]
[1] "political"



[[1]]$results[[1]]$address_components[[5]]
[[1]]$results[[1]]$address_components[[5]]$long_name
[1] "Wellington"

[[1]]$results[[1]]$address_components[[5]]$short_name
[1] "Wellington"

[[1]]$results[[1]]$address_components[[5]]$types
[[1]]$results[[1]]$address_components[[5]]$types[[1]]
[1] "administrative_area_level_1"

[[1]]$results[[1]]$address_components[[5]]$types[[2]]
[1] "political"



[[1]]$results[[1]]$address_components[[6]]
[[1]]$results[[1]]$address_components[[6]]$long_name
[1] "New Zealand"

[[1]]$results[[1]]$address_components[[6]]$short_name
[1] "NZ"

[[1]]$results[[1]]$address_components[[6]]$types
[[1]]$results[[1]]$address_components[[6]]$types[[1]]
[1] "country"

[[1]]$results[[1]]$address_components[[6]]$types[[2]]
[1] "political"



[[1]]$results[[1]]$address_components[[7]]
[[1]]$results[[1]]$address_components[[7]]$long_name
[1] "6021"

[[1]]$results[[1]]$address_components[[7]]$short_name
[1] "6021"

[[1]]$results[[1]]$address_components[[7]]$types
[[1]]$results[[1]]$address_components[[7]]$types[[1]]
[1] "postal_code"




[[1]]$results[[1]]$formatted_address
[1] "27 Hall Street, Newtown, Wellington 6021, New Zealand"

[[1]]$results[[1]]$geometry
[[1]]$results[[1]]$geometry$bounds
[[1]]$results[[1]]$geometry$bounds$northeast
[[1]]$results[[1]]$geometry$bounds$northeast$lat
[1] -41.31066

[[1]]$results[[1]]$geometry$bounds$northeast$lng
[1] 174.7768


[[1]]$results[[1]]$geometry$bounds$southwest
[[1]]$results[[1]]$geometry$bounds$southwest$lat
[1] -41.31081

[[1]]$results[[1]]$geometry$bounds$southwest$lng
[1] 174.7766



[[1]]$results[[1]]$geometry$location
[[1]]$results[[1]]$geometry$location$lat
[1] -41.31074

[[1]]$results[[1]]$geometry$location$lng
[1] 174.7767


[[1]]$results[[1]]$geometry$location_type
[1] "ROOFTOP"

[[1]]$results[[1]]$geometry$viewport
[[1]]$results[[1]]$geometry$viewport$northeast
[[1]]$results[[1]]$geometry$viewport$northeast$lat
[1] -41.30932

[[1]]$results[[1]]$geometry$viewport$northeast$lng
[1] 174.778


[[1]]$results[[1]]$geometry$viewport$southwest
[[1]]$results[[1]]$geometry$viewport$southwest$lat
[1] -41.31202

[[1]]$results[[1]]$geometry$viewport$southwest$lng
[1] 174.7753




[[1]]$results[[1]]$place_id
[1] "ChIJiynBCOOvOG0RMx429ZNDR3A"

[[1]]$results[[1]]$types
[[1]]$results[[1]]$types[[1]]
[1] "premise"




[[1]]$status
[1] "OK"
---
versb
  • 91
  • 5
  • 1
    Are you able to provide an example of what the return is from the `geocode()` call? My guess is that the "mess of listed lists" is actually a JSON response, in which case you can probably find the right keys/values and go from there... – rossdrucker9 Aug 04 '22 at 02:26
  • Done - I added an example using the first list element (address). I should mention the lists are of varying sizes but I think if I just use NA for elements that exist in one list and not another when I combine them in a dataframe that would be fine – versb Aug 04 '22 at 03:40
  • Try to post your data in the form of a reproducible example (using e.g. `dput()`), see also: https://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example – Joris C. Aug 04 '22 at 06:38
  • It is reproducible I just cant share my google API key – versb Aug 04 '22 at 06:41
  • The printed output is of little use to replicate the nested list and I don't have a google API key, so cannot really do much except for manually recreating the list based on the printed results – Joris C. Aug 04 '22 at 10:07
  • Ah I see - I apologise - looks to be solved now so no worries and I will check that link for my next post. Thank you – versb Aug 04 '22 at 19:58

1 Answers1

1

You can explore the nested lists with viewer in Rstudio or listviewer::jsonedit. You can then drill down to the desired information. Basically using unnest_wider to spread the list to columns to then select desired columns and unnest_longer to tease out nested lists to then iterate through.

library(tidyverse)
map(random_addresses, ~geocode(.x, output = "all") %>% 
  # results is name of list with desired information, create tibble for unnest
  tibble(output = .$results) %>% 
  # Create tibble with address_components as column-list
  unnest_wider(output) %>% 
  dplyr::select(address_components) %>% 
  # Get address_components as list of lists, each list to df
  unnest_longer(., col = "address_components") %>% 
  map_dfr(., ~.x) %>% 
  # types is the type of information. It is listed so unlist
  mutate(types = unlist(types)) %>% 
  # Choose the information to keep
  filter(types %in% c("street_number", "route")) %>% 
  # Choose the format of data
  select(long_name, types) %>% 
  # Put in wide form
  pivot_wider(names_from = "types", values_from = "long_name")
) %>%
bind_rows # create master df

It will give you lists with your information (before filtering)

[[4]]
# A tibble: 13 × 3
   long_name     short_name    types                      
   <chr>         <chr>         <chr>                      
 1 New Zealand   NZ            country                    
 2 New Zealand   NZ            political                  
 3 42            42            street_number              
 4 Elden Drive   Elden Dr      route                      
 5 Saddle River  Saddle River  locality                   
 6 Saddle River  Saddle River  political                  
 7 Bergen County Bergen County administrative_area_level_2
 8 Bergen County Bergen County political                  
 9 New Jersey    NJ            administrative_area_level_1
10 New Jersey    NJ            political                  
11 United States US            country                    
12 United States US            political                  
13 07458         07458         postal_code   
Brian Syzdek
  • 873
  • 6
  • 10