我在简单要素中保存了多个轨迹类型为POINT
的(sf
)。我想计算后续位置之间的欧氏距离(即行)。直到现在,我已经使用毕达哥拉斯公式“手动”计算了2D空间中的欧氏距离。我想知道我是否可以使用函数sf::st_distance()
来做同样的事情。下面是一个简单的例子:
library(sf)
library(dplyr)
set.seed(1)
df <- data.frame(
gr = c(rep("a",5),rep("b",5)),
x = rnorm(10),
y = rnorm(10)
)
df <- st_as_sf(df,coords = c("x","y"),remove = F)
df %>%
group_by(gr) %>%
mutate(
dist = sqrt((lead(x)-x)^2+(lead(y)-y)^2)
)
#> Simple feature collection with 10 features and 4 fields
#> geometry type: POINT
#> dimension: XY
#> bbox: xmin: -0.8356286 ymin: -2.2147 xmax: 1.595281 ymax: 1.511781
#> epsg (SRID): NA
#> proj4string: NA
#> # A tibble: 10 x 5
#> # Groups: gr [2]
#> gr x y dist geometry
#> <fct> <dbl> <dbl> <dbl> <POINT>
#> 1 a -0.626 1.51 1.38 (-0.6264538 1.511781)
#> 2 a 0.184 0.390 1.44 (0.1836433 0.3898432)
#> 3 a -0.836 -0.621 2.91 (-0.8356286 -0.6212406)
#> 4 a 1.60 -2.21 3.57 (1.595281 -2.2147)
#> 5 a 0.330 1.12 NA (0.3295078 1.124931)
#> 6 b -0.820 -0.0449 1.31 (-0.8204684 -0.04493361)
#> 7 b 0.487 -0.0162 0.992 (0.4874291 -0.01619026)
#> 8 b 0.738 0.944 0.204 (0.7383247 0.9438362)
#> 9 b 0.576 0.821 0.910 (0.5757814 0.8212212)
#> 10 b -0.305 0.594 NA (-0.3053884 0.5939013)
我想用sf::st_distance()
来计算dist
。我该怎么做?
2条答案
按热度按时间uqxowvwt1#
关于
sf
,首先要知道的是几何列(类sfc
的一个)被存储为dataframe中的列表列。通常使用列表列的关键是使用purrr::map
和朋友,或者使用一个接受列表列作为参数的函数。在st_distance
的情况下,它的参数可以是sf
(一个 Dataframe ),sfc
(几何列),甚至是sfg
(一个几何行)的对象,所以不需要map
和朋友。解决方案应该看起来像这样:然而,这并不起作用。经过一些调查,我们发现了两个问题。首先,
st_distance
返回一个距离矩阵,而不是一个单一的值。为了解决这个问题,我们使用st_distance
的by_element = T
参数。接下来,我们不能只做
dist = st_distance(geometry, lead(geometry), by_element = T)
,因为lead
只对向量列有效,而不是列表列。为了解决第二个问题,我们自己使用
geometry[row_number() + 1]
创建了引导列。以下是完整的解决方案:
r6hnlfcb2#
下面是一个基本的
R
解决方案。split()
组列的 Dataframehead()
和tail()
计算后续位置之间的距离NA
附加到结果中(因为最后一个位置没有后续位置)do.call()
中的rbind
将生成的sf
对象重新绑定在一起。