Geosphere/dplyr: 创建坐标间距离矩阵
Geosphere/dplyr: create matrix of distance between coordinates
我想创建一个 "matrix" 多个坐标之间的距离。最好使用 dplyr/geosphere。我已经看到 geosphere 包提供了这个。我设法创建了两个向量之间的距离,但我很难创建完整的矩阵。
这是具有多个坐标的示例table。
df <- data.frame(latitude = c(49.48609,-8.14671,11.28625),
longitude = c(8.463678,143.05793,-11.18285))
latitude longitude
1 49.48609 8.463678
2 -8.14671 143.057930
3 11.28625 -11.182850
这是我正在寻找的输出:
latitude longitude distance-latlon1 distance-latlon2 distance-latlon3
1 49.48609 8.463678 NA *latlon2><latlon1 *latlon3><latlon1
2 -8.14671 143.057930 *latlon1><latlon2 NA *latlon3><latlon2
3 11.28625 -11.182850 *latlon1><latlon3 *latlon2><latlon3 NA
我尝试使用 geosphere,但我只找到了一种计算两列之间距离的方法(在此代码段中结果为 0)。
library(geosphere)
df$distance <- distVincentyEllipsoid(df[,c('longitude','latitude')],
df[,c('longitude','latitude')])
我们可以使用 sf
包中的 st_distance
函数,如果 sf
对象处于经纬度,它使用 geosphere
中的函数来计算距离投影(EPSG 4326)。 df2
是示例输出。
# Load packages
library(dplyr)
library(sf)
# Create example data frame
df <- data.frame(latitude = c(49.48609,-8.14671,11.28625),
longitude = c(8.463678,143.05793,-11.18285))
# COnvert to sf object
df_sf <- st_as_sf(df, coords = c("longitude", "latitude"))
# Set the projection as ESPG 4326 (long_lat)
st_crs(df_sf) <- 4326
# Apply the st_distance function
dist_m <- st_distance(df_sf)
# Combine with df
df2 <- df %>%
mutate(`distance-latlon1` = as.numeric(dist_m[, 1]),
`distance-latlon2` = as.numeric(dist_m[, 2]),
`distance-latlon3` = as.numeric(dist_m[, 3]))
# Replace 0 with NA
df2[df2 == 0] <- NA
df2
latitude longitude distance-latlon1 distance-latlon2 distance-latlon3
1 49.48609 8.463678 NA 13792423 4606658
2 -8.14671 143.057930 13792423 NA 17189185
3 11.28625 -11.182850 4606658 17189185 NA
这是将 dist_m
与 df
组合的另一种方法。
library(tidyr)
# Convert dist_m to data frame
dist_df <- dist_m %>%
as.table() %>%
as_data_frame() %>%
spread(Var2, n) %>%
select(-Var1) %>%
mutate_all(as.numeric) %>%
setNames(paste0("distance-latlon", 1:nrow(df)))
# Combine with df
df2 <- df %>%
bind_cols(dist_df)
# Replace 0 with NA
df2[df2 == 0] <- NA
您需要 geosphere
软件包的 distm
功能。有:
# create a distance matrix
m <- distm(df[2:1], df[2:1], fun = distVincentyEllipsoid)
# replace the diagonal with NA
diag(m) <- NA
# make column names for the distance matrix
colnames(m) <- paste0('r',1:nrow(df))
# bind the distance matrix to the dataframe
cbind.data.frame(df, m)
你得到:
latitude longitude r1 r2 r3
1 49.48609 8.463678 NA 13792423 4606658
2 -8.14671 143.057930 13792423 NA 17189185
3 11.28625 -11.182850 4606658 17189185 NA
而不是 distVincentyEllipsoid
我会使用更快更精确的 distGeo
df = df[,2:1] # the order should be longitude, latitude!
distm(df, df, distGeo)
或
library(raster)
d <- pointDistance(df)
也许后面是
as.matrix(as.dist(d))
我想创建一个 "matrix" 多个坐标之间的距离。最好使用 dplyr/geosphere。我已经看到 geosphere 包提供了这个。我设法创建了两个向量之间的距离,但我很难创建完整的矩阵。
这是具有多个坐标的示例table。
df <- data.frame(latitude = c(49.48609,-8.14671,11.28625),
longitude = c(8.463678,143.05793,-11.18285))
latitude longitude
1 49.48609 8.463678
2 -8.14671 143.057930
3 11.28625 -11.182850
这是我正在寻找的输出:
latitude longitude distance-latlon1 distance-latlon2 distance-latlon3
1 49.48609 8.463678 NA *latlon2><latlon1 *latlon3><latlon1
2 -8.14671 143.057930 *latlon1><latlon2 NA *latlon3><latlon2
3 11.28625 -11.182850 *latlon1><latlon3 *latlon2><latlon3 NA
我尝试使用 geosphere,但我只找到了一种计算两列之间距离的方法(在此代码段中结果为 0)。
library(geosphere)
df$distance <- distVincentyEllipsoid(df[,c('longitude','latitude')],
df[,c('longitude','latitude')])
我们可以使用 sf
包中的 st_distance
函数,如果 sf
对象处于经纬度,它使用 geosphere
中的函数来计算距离投影(EPSG 4326)。 df2
是示例输出。
# Load packages
library(dplyr)
library(sf)
# Create example data frame
df <- data.frame(latitude = c(49.48609,-8.14671,11.28625),
longitude = c(8.463678,143.05793,-11.18285))
# COnvert to sf object
df_sf <- st_as_sf(df, coords = c("longitude", "latitude"))
# Set the projection as ESPG 4326 (long_lat)
st_crs(df_sf) <- 4326
# Apply the st_distance function
dist_m <- st_distance(df_sf)
# Combine with df
df2 <- df %>%
mutate(`distance-latlon1` = as.numeric(dist_m[, 1]),
`distance-latlon2` = as.numeric(dist_m[, 2]),
`distance-latlon3` = as.numeric(dist_m[, 3]))
# Replace 0 with NA
df2[df2 == 0] <- NA
df2
latitude longitude distance-latlon1 distance-latlon2 distance-latlon3
1 49.48609 8.463678 NA 13792423 4606658
2 -8.14671 143.057930 13792423 NA 17189185
3 11.28625 -11.182850 4606658 17189185 NA
这是将 dist_m
与 df
组合的另一种方法。
library(tidyr)
# Convert dist_m to data frame
dist_df <- dist_m %>%
as.table() %>%
as_data_frame() %>%
spread(Var2, n) %>%
select(-Var1) %>%
mutate_all(as.numeric) %>%
setNames(paste0("distance-latlon", 1:nrow(df)))
# Combine with df
df2 <- df %>%
bind_cols(dist_df)
# Replace 0 with NA
df2[df2 == 0] <- NA
您需要 geosphere
软件包的 distm
功能。有:
# create a distance matrix
m <- distm(df[2:1], df[2:1], fun = distVincentyEllipsoid)
# replace the diagonal with NA
diag(m) <- NA
# make column names for the distance matrix
colnames(m) <- paste0('r',1:nrow(df))
# bind the distance matrix to the dataframe
cbind.data.frame(df, m)
你得到:
latitude longitude r1 r2 r3 1 49.48609 8.463678 NA 13792423 4606658 2 -8.14671 143.057930 13792423 NA 17189185 3 11.28625 -11.182850 4606658 17189185 NA
而不是 distVincentyEllipsoid
我会使用更快更精确的 distGeo
df = df[,2:1] # the order should be longitude, latitude!
distm(df, df, distGeo)
或
library(raster)
d <- pointDistance(df)
也许后面是
as.matrix(as.dist(d))