使用dplyr :: mutate计算到数据点的地理距离

Sim*_*ard 3 r dplyr tidyverse geosphere

我试图使用R与tidyverse包,并在将函数应用于我的数据时遇到问题.我的数据包括纬度/经度坐标,我想计算从每个位置(我的数据帧的行)到参考位置的距离.我正在尝试使用geosphere :: distm函数.

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
)
Run Code Online (Sandbox Code Playgroud)

我使用该rowwise()函数,如上所述,但这已被弃用,所以我想知道如何使用现代tidyverse,即,dplyr或者purrr,我认为,例如我最接近的是使用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
)
Run Code Online (Sandbox Code Playgroud)

到目前为止,我失败了.

Lam*_*mia 7

您可以使用distHaversine代替distm, 和cbind

data %>%  mutate(dist = distHaversine(cbind(myLong, myLat), cbind(long, lat)))
Run Code Online (Sandbox Code Playgroud)

示例数据:

myLong = 172
myLat = -43 
long = c(180,179,179)
lat = c(-40,-41,-40)
data = data.frame(myLong,myLat,long,lat)
Run Code Online (Sandbox Code Playgroud)

结果如下:

  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
Run Code Online (Sandbox Code Playgroud)


Psi*_*dom 6

你可以用mutatemapply:

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
Run Code Online (Sandbox Code Playgroud)

更新使用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
Run Code Online (Sandbox Code Playgroud)

使用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
Run Code Online (Sandbox Code Playgroud)