I have a data frame df
containing multiple observations with UK Postcode values. I want to create a new column which calculates the distance between the postcodes in df$origin and df$dest for each observation.
I haven't got funding for Google Maps API and was wondering if I can do this with PostcodeioR
? Or is there an alternate free way of doing this in RStudio?
# MRE
origin <- c("S6 2PA", "S35 0DP", "M1 6BD", "DE55 4JF")
dest <- c("S5 7AU", "S5 7AU", "S5 7AU", "S5 7AU")
df <- tibble(origin,dest)
Preferably, the distance created would be the driving distance, rather than as the crow flies, however I appreciate this may not be possible.
The PoscodesioR package will look up your postcodes and tell you their longitude/latitude, so you can get the "crow-flies" distance using any of several methods such as geosphere::distHaversine
library(tidyverse)
library(PostcodesioR)
library(geosphere)
origin <- c("S6 2PA", "S35 0DP", "M1 6BD", "DE55 4JF")
dest <- c("S5 7AU", "S5 7AU", "S5 7AU", "S5 7AU")
df <- tibble(origin, dest)
df %>%
mutate(miles = map2(origin, dest,
~ distHaversine(postcode_lookup(.x)[,7:8],
postcode_lookup(.y)[,7:8])/1609.34) |>
unlist())
#> # A tibble: 4 x 3
#> origin dest distance
#> <chr> <chr> <dbl>
#> 1 S6 2PA S5 7AU 1.98
#> 2 S35 0DP S5 7AU 4.63
#> 3 M1 6BD S5 7AU 32.5
#> 4 DE55 4JF S5 7AU 23.0
These all look pretty accurate on direct measurements.
I'm not aware of a completely free API that allows measurement of driving distances. Getting a Google API key will allow you to get driving distances, and as far as I can tell you should be able to get about 40,000 measurements per month for free. You should be able to lookup and store the driving distance between all South Yorkshire postcodes and the Northern General Hospital over a two-month period free of charge. Depending on your project size, you may not need funding at all (though if you had to measure the driving distance between all 1.7 million UK postcodes and the Northern General Hospital then that would cost you about £7,000...).
EDIT
If you have a Google API key and billing set up, it may be just as easy to use the API directly. The following function will give you driving distances and times if you have registered your API key with ggmap
driving_dist <- function(origins, destinations) {
do.call("rbind", Map(function(x, y) {
res <- paste0("https://maps.googleapis.com/maps/api/distancematrix/json",
"?destinations=", URLencode(x),
"&origins=", URLencode(y),
"&units=imperial",
"&key=", ggmap::google_key()) |>
httr::GET() |>
httr::content()
data.frame(distance_metres = res$rows[[1]]$elements[[1]]$distance$value,
time_seconds = res$rows[[1]]$elements[[1]]$duration$value)
}, origins, destinations)
)
}
Testing, we have:
df %>% mutate(driving_dist(origin, dest))
# A tibble: 4 x 4
#> origin dest distance_metres time_seconds
#> <chr> <chr> <int> <int>
#> 1 S6 2PA S5 7AU 5869 832
#> 2 S35 0DP S5 7AU 10145 1198
#> 3 M1 6BD S5 7AU 63816 4763
#> 4 DE55 4JF S5 7AU 53346 2861