I am trying to use R with the tidyverse packages and having trouble applying a function to my data. My data includes lat/long coordinates, and I want to calculate the distance from every location (row of my data frame) to a reference location. I am trying to use the geosphere::distm function.
library(tidyverse)
library(geosphere)
my_long <- 172
my_lat <- -43
data <- data %>% rowwise() %>% mutate(
dist = distm(c(myLong, myLat), c(long, lat), fun=distHaversine) # this works
)
I got it working using the rowwise()
function, as above, but this is deprecated, so I want to know how to do it with modern tidyverse
, i.e., dplyr
or purrr
, I think, for example the closest I have got is using map2:
my_distm <- function(long1, lat1, long2, lat2)
distm(c(long1, lat1), c(long2, lat2), fun=distHaversine)
data <- data %>% mutate(
dist = map2(long, lat, my_distm, my_long, my_lat) # this doesn't
)
So far I have failed.
You could use distHaversine
instead of distm
, and cbind
:
data %>% mutate(dist = distHaversine(cbind(myLong, myLat), cbind(long, lat)))
Example data:
myLong = 172
myLat = -43
long = c(180,179,179)
lat = c(-40,-41,-40)
data = data.frame(myLong,myLat,long,lat)
Which gives as result:
myLong myLat long lat dist
1 172 -43 180 -40 745481.0
2 172 -43 179 -41 620164.8
3 172 -43 179 -40 672076.2
You can use mutate
with mapply
:
library(tidyverse)
library(geosphere)
my_long <- 172
my_lat <- -43
df <- data.frame(long = c(170, 180), lat = c(-43, 43))
df %>% rowwise() %>% mutate(
dist = distm(c(my_long, my_lat), c(long, lat), fun=distHaversine) # this works
)
#Source: local data frame [2 x 3]
#Groups: <by row>
# A tibble: 2 x 3
# long lat dist
# <dbl> <dbl> <dbl>
#1 170 -43 162824
#2 180 43 9606752
df %>% mutate(
dist = mapply(function(lg, lt) distm(c(my_long, my_lat), c(lg, lt), fun=distHaversine), long, lat)
)
# long lat dist
#1 170 -43 162824
#2 180 43 9606752
Update on using map2
:
df %>%
mutate(dist = map2(long, lat, ~distm(c(my_long, my_lat), c(.x, .y), fun=distHaversine)))
# here .x stands for a value from long column, and .y stands for a value from lat column
# long lat dist
#1 170 -43 162824
#2 180 43 9606752
To use my_distm
:
my_distm <- function(long1, lat1, long2, lat2)
distm(c(long1, lat1), c(long2, lat2), fun=distHaversine)
df %>% mutate(dist = map2(long, lat, ~my_distm(my_long, my_lat, .x, .y)))
# long lat dist
#1 170 -43 162824
#2 180 43 9606752
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With