[英]compute pointwise distance by group in R with sf dplyr
I have 2 dataframes. 我有2个数据框。 I want to compute the distance between all POINT geometries if the first frame with respect to a certain POINT in the second dataframe.
如果第一帧相对于第二个数据帧中的某个POINT,我想计算所有POINT几何之间的距离。 The main feature of this problem is that I have a grouping variable in the first dataframe, and I would like to select the corresponding point to measure the distance to (in the second dataframe) according to this grouping indicator.
这个问题的主要特征是,我在第一个数据帧中有一个分组变量,并且我想根据该分组指示符选择相应的点以测量到(在第二个数据帧中)的距离。 I tried with
group_by
: 我尝试了
group_by
:
library(sf)
library(dplyr)
d = data.frame(x = 1:10,y = 1:10, g = rep(c("a","b"),each=5))
d_sf = st_as_sf(d,coords = c("x","y") )
d_sf
Simple feature collection with 10 features and 1 field
geometry type: POINT
dimension: XY
bbox: xmin: 1 ymin: 1 xmax: 10 ymax: 10
epsg (SRID): NA
proj4string: NA
g geometry
1 a POINT (1 1)
2 a POINT (2 2)
3 a POINT (3 3)
4 a POINT (4 4)
5 a POINT (5 5)
6 b POINT (6 6)
7 b POINT (7 7)
8 b POINT (8 8)
9 b POINT (9 9)
10 b POINT (10 10)
centers = d %>% group_by(g) %>% summarise(x = mean(x), y = mean(y))
centers
centers_sf = st_as_sf(centers, coords = c("x","y"))
Simple feature collection with 2 features and 1 field
geometry type: POINT
dimension: XY
bbox: xmin: 3 ymin: 3 xmax: 8 ymax: 8
epsg (SRID): NA
proj4string: NA
# A tibble: 2 x 2
g geometry
<fct> <POINT>
1 a (3 3)
2 b (8 8)
d_sf %>% group_by(g) %>% st_distance(centers_sf,by_element = TRUE)
[1] 2.828427 8.485281 0.000000 5.656854 2.828427 2.828427 5.656854 0.000000 8.485281 2.828427
# but really I want this:
> st_distance(d_sf[1,],centers_sf[1,])
[,1]
[1,] 2.828427
> st_distance(d_sf[2,],centers_sf[1,])
[,1]
[1,] 1.414214
> st_distance(d_sf[3,],centers_sf[1,])
[,1]
[1,] 0
Is this what you are looking for? 这是你想要的?
library(tidyverse)
d_sf %>%
mutate(dst = map2_dbl(g, geometry,
~ st_distance(.y, centers_sf %>% filter(g == .x) %>% pull(geometry))
))
Output: 输出:
g dst geometry
1 a 2.828427 POINT (1 1)
2 a 1.414214 POINT (2 2)
3 a 0.000000 POINT (3 3)
4 a 1.414214 POINT (4 4)
5 a 2.828427 POINT (5 5)
6 b 2.828427 POINT (6 6)
7 b 1.414214 POINT (7 7)
8 b 0.000000 POINT (8 8)
9 b 1.414214 POINT (9 9)
10 b 2.828427 POINT (10 10)
Here's a slightly modified answer that works when crs is defined: 这是定义了crs时可以稍作修改的答案:
d_sf$dst <- map_dbl(1:nrow(d_sf), function(x){
x <- d_sf[x,]
y <- centers_sf[centers_sf$g == x$g,]
st_distance(x, y)
})
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.