最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

tidyverse - R distance to first point of SpatVect points - Stack Overflow

programmeradmin1浏览0评论

I have a spatial vector (Spatvector) with points arranged in groups. I want to calculate the distance of each point to the first point in the group.

    Trans2024_df
    Name  Distance_to_first
1   T01   0
2   T01   1.2
3   T01   2.5
4   T02   0
5   T02   0.5
6   T02   1.2
7   T02   1.7
8   T03   0
9   T03   1.3

I managed to get the distance to the previous point.

VectorPoints_sf <- st_as_sf(VectorPoints)

VectorPoints_sf %>%
  mutate(
    distance_next = sf::st_distance(
      geometry, 
      lead(geometry), 
      by_element = TRUE))

    Name  distance_next
1   T01   0
2   T01   1.2
3   T01   1.3
4   T02   5
5   T02   0.5
6   T02   0.7
7   T02   1.5
8   T03   2
9   T03   1.3

But I can't figure out how to get the distance to the first point. I assumed that it would work with dplr::first()

VectorPoints_sf %>%
  group_by(Transect) %>%
  mutate(
    distance_first = sf::st_distance(
      geometry, 
      first(geometry), 
      by_element = TRUE))

But I get the following error:

    Error in `stopifnot()`:
ℹ In argument: `distance_first = sf::st_distance(geometry, geometry[1], by_element = TRUE)`.
ℹ In group 1: `Transect = "T09"`.
Caused by error in `sf::st_distance()`:
! length(x) == length(y) is not TRUE

I have a spatial vector (Spatvector) with points arranged in groups. I want to calculate the distance of each point to the first point in the group.

    Trans2024_df
    Name  Distance_to_first
1   T01   0
2   T01   1.2
3   T01   2.5
4   T02   0
5   T02   0.5
6   T02   1.2
7   T02   1.7
8   T03   0
9   T03   1.3

I managed to get the distance to the previous point.

VectorPoints_sf <- st_as_sf(VectorPoints)

VectorPoints_sf %>%
  mutate(
    distance_next = sf::st_distance(
      geometry, 
      lead(geometry), 
      by_element = TRUE))

    Name  distance_next
1   T01   0
2   T01   1.2
3   T01   1.3
4   T02   5
5   T02   0.5
6   T02   0.7
7   T02   1.5
8   T03   2
9   T03   1.3

But I can't figure out how to get the distance to the first point. I assumed that it would work with dplr::first()

VectorPoints_sf %>%
  group_by(Transect) %>%
  mutate(
    distance_first = sf::st_distance(
      geometry, 
      first(geometry), 
      by_element = TRUE))

But I get the following error:

    Error in `stopifnot()`:
ℹ In argument: `distance_first = sf::st_distance(geometry, geometry[1], by_element = TRUE)`.
ℹ In group 1: `Transect = "T09"`.
Caused by error in `sf::st_distance()`:
! length(x) == length(y) is not TRUE
Share Improve this question asked Mar 6 at 16:53 macemace 5081 gold badge7 silver badges24 bronze badges 2
  • 1 Try without by_element = TRUE. – margusl Commented Mar 6 at 17:30
  • Can you please edit your code to make it a minimal, self-contained, reproducible example. That is, create a SpatVector with code, and take it from there. – Robert Hijmans Commented Mar 7 at 17:07
Add a comment  | 

1 Answer 1

Reset to default 0

Example data

library(terra)
set.seed(1)
v <- vect(matrix(runif(40), ncol=2), crs="local")
v$Name <- rep(LETTERS[1:5], each=4)

Computing the distances can be done like this

x <- lapply(split(v, "Name"), \(x) distance(x[-1], x[1]))

Or like this to create the output data.frame you want, and checking for the degenerate case where there is only a single point

x <- lapply(split(v, "Name"), \(x) { 
   if (nrow(x) == 1) {
      dist <- NA
   } else {
      dist <- distance(x[-1], x[1])
   } 
   data.frame(Name=x[1]$Name, dist=dist)
})
 
do.call(rbind, x)
#   Name      dist
#1     A 0.7303860
#2     A 0.4178128
#3     A 1.0333374
#4     B 0.7067796
#5     B 0.7851554
#6     B 0.4733401
#7     C 0.7759276
#8     C 0.5738372
#9     C 0.5270442
#10    D 0.4315181
#11    D 0.3439516
#12    D 0.2577641
#13    E 0.7390779
#14    E 0.3448722
#15    E 0.3876103

If you wanted the sequential distance by group instead, and the data are sorted by group, you could do

dst <- data.frame(Name=v$Name, d=distance(v, sequential=TRUE))
i <- which(v$Name[-1] != v$Name[-nrow(v)]) + 1
dst$d[i] <- 0
发布评论

评论列表(0)

  1. 暂无评论