Reputation: 14317
I have the following simple use-case where I define two samples containing name and location:
if(!require(tidyverse)) install.packages("tidyverse", repos = "http://cran.us.r-project.org")
if(!require(ggmap)) devtools::install_github("dkahle/ggmap")
# you may also need to
#register_google(key="<register your own key>")
x <- tibble(name=c('a', 'b'), loc=c('china', 'switzerland'))
x
# A tibble: 2 x 2
name loc
<chr> <chr>
1 a china
2 b switzerland
Now I'd like to enrich my tibble with longitude and latitude information. I do that by running:
x %>%
mutate(lon=geocode(loc)$lon, lat=geocode(loc)$lat)
but this is expensive because I'd need to call the geocode
function two times per sample and that [s] ain't free. Is there a way to flatten the return of the geocode
function into the tibble? This is a failed attempt and a demonstration of what I'm trying to achieve:
x %>%
mutate(xx=geocode(loc), lon=xx$lon, lat=xx$lat)
>Error: Column `xx` is of unsupported class data.frame
Upvotes: 1
Views: 214
Reputation: 16862
For the specific case of adding geocoded coordinates, ggmap
actually has a function mutate_geocode
that does exactly this:
library(dplyr)
library(ggmap)
mutate_geocode(x, location = loc)
#> # A tibble: 2 x 4
#> name loc lon lat
#> <chr> <chr> <dbl> <dbl>
#> 1 a china 104. 35.9
#> 2 b switzerland 8.23 46.8
For more general uses, purrr::map_*
functions work well. You can map over location names, apply geocode
, and unnest that list:
mutate(x, coords = purrr::map(loc, geocode)) %>%
tidyr::unnest(coords)
# same output as above
You could also extract each column you need with purrr::map_dbl
. This might be helpful if you got a data frame back with more than just lon and lat columns, such as if you'd set a different value of output
in geocode
:
mutate(x, coords = purrr::map(loc, geocode),
lon = purrr::map_dbl(coords, "lon"),
lat = purrr::map_dbl(coords, "lat"))
# same output as above
Or by column position:
mutate(x, coords = purrr::map(loc, geocode),
lon = purrr::map_dbl(coords, 1),
lat = purrr::map_dbl(coords, 2))
# same output
Upvotes: 1
Reputation: 887711
The output of geocode can be placed in a list
, and then extract the components
library(dplyr)
library(purrr)
library(ggmap)
library(tidyr)
x %>%
mutate(xx = map(loc, geocode),
out = map(xx, ~ tibble(lon = .x$lon, lat = .x$lat))) %>%
unnest_wider(c(out))
Upvotes: 1