【问题标题】:Calculating distance between consecutive projected coordinates within individuals (adding distance column?)计算个人内连续投影坐标之间的距离(添加距离列?)
【发布时间】:2021-10-27 01:52:00
【问题描述】:

我有一个包含不同个体和投影坐标的运动数据集。使用以下代码将坐标投影到 UTM 中:

coordinates(data) = ~x+y #turns data into spatial data frame
proj4string(data) <- CRS("+init=epsg:4326")
data <- spTransform(data, CRS("+init=epsg:5321")) #denotes what CRS to use, this changes the data into UTMs from lat/long, which projects the data
data <- as.data.frame(data)

我想计算个人内连续位置之间的距离(以米为单位)。只要点之间保持一致,我就可以接受相当大的误差范围。

这是我的数据集示例:

ID      x         y    
Bear1   459486.4  7181992
Bear1   459652.6  7181904
Bear1   459661.5  7181880
Bear2   459604.7  7181898
Bear2   459639.6  7181894
Bear2   459565.1  7181960

理想情况下,我希望在此数据集中添加一个距离列,显示点内的距离。

【问题讨论】:

  • 您需要提供更多信息,即投影的坐标系。同时看看 sf 包。
  • 感谢您的帮助。坐标在 UTM 投影中。我将编辑问题以指定这一点。

标签: r coordinates distance sf


【解决方案1】:

请在下面找到显示sf 包解决方案的代表。

如果我没记错的话,您提供的数据已经在 EPSG:5321 中。假设这样,您只需要输入以下几行代码即可获得所有可能的点对之间的距离矩阵。

Reprex

  • 代码
library(sf)

data <- st_as_sf(data, coords = c("x", "y"), crs = 5321)
distances <- st_distance(data)
distances
#> Units: [m]
#>           [,1]      [,2]      [,3]      [,4]      [,5]      [,6]
#> [1,]   0.00000 188.05967 207.85574 151.09894 181.86325  84.95699
#> [2,] 188.05967   0.00000  25.59707  48.27432  16.40122 103.88575
#> [3,] 207.85574  25.59707   0.00000  59.58389  25.99250 125.27155
#> [4,] 151.09894  48.27432  59.58389   0.00000  35.12848  73.56738
#> [5,] 181.86325  16.40122  25.99250  35.12848   0.00000  99.53015
#> [6,]  84.95699 103.88575 125.27155  73.56738  99.53015   0.00000

reprex package (v0.3.0) 于 2021 年 10 月 27 日创建

如果你想从头开始,即从地理坐标开始(即EPSG = 4326),你必须按照以下步骤进行:

library(sf)

data <- st_as_sf(data, coords = c("x", "y"), crs = 4326)
data <- st_transform(data, crs = 5321)
distances <- st_distance(data)
distances
  • 您的数据
data <- data.frame(ID = c("Bear1", "Bear1", "Bear1", "Bear2", "Bear2", "Bear2"),
                   x = c(459486.4, 459652.6, 459661.5, 459604.7, 459639.6, 459565.1),
                   y = c(7181992, 7181904, 7181880, 7181898, 7181894, 7181960))

编辑以回答您的评论

library(sf)
library(dplyr)
library(data.table)
library(units)

# Same code as above (but in a tidyverse version and with drop_units function) to get the distance matrix (i.e. data2)
data2 <- data %>% st_as_sf(coords = c("x", "y"), crs = 5321) %>% 
  group_by(ID) %>% 
  st_distance() %>% 
  drop_units()

# Extraction of the relevant values from the distance matrix 
data2 <- setnames(setDT(as.data.frame(data2[row(data2) == col(data2)+1])), 1, "Distance")

# Add a NA row at the end of data2
data2 <- rbindlist(list(data2, list(NA)))[, Index := 1:.N][]

# Join data and data2 on 'Index' column
Results <- setDT(data)[, Index :=  1:.N
                       ][data2, on = .(Index)
                         ][, Index := NULL][]

# Set NA at the last row of each group (i.e. each Bear) for the 'Distance' column
Results[Results[, .(idLast = .I[.N]), by=ID]$idLast, Distance := NA][]
#>       ID        x       y  Distance
#> 1: Bear1 459486.4 7181992 188.05967
#> 2: Bear1 459652.6 7181904  25.59707
#> 3: Bear1 459661.5 7181880        NA
#> 4: Bear2 459604.7 7181898  35.12848
#> 5: Bear2 459639.6 7181894  99.53015
#> 6: Bear2 459565.1 7181960        NA

reprex package (v2.0.1) 于 2021-11-04 创建

【讨论】:

  • 谢谢!不过,我一直在寻找连续位置之间的距离(我的错-我编辑了问题以显示这一点)。你会碰巧知道怎么做吗?
  • 你好@Cam。请在上方找到编辑以回答您的评论。我希望这是你想要的。如果是这样,请将答案标记为已验证。如果没有,请告诉我有什么问题。干杯。
  • 太好了,谢谢!
  • 很高兴能为您提供帮助。我祝你工作顺利。干杯。
猜你喜欢
  • 2013-02-21
  • 1970-01-01
  • 2020-02-12
  • 2010-09-26
  • 2018-06-12
  • 1970-01-01
  • 2021-09-08
  • 2020-06-02
  • 2021-04-05
相关资源
最近更新 更多