计算个体内连续投影坐标之间的距离(添加距离列?)

Calculating distance between consecutive projected coordinates within individuals (adding distance column?)

我有一个包含不同个体和投影坐标的运动数据集。使用以下代码将坐标投影到 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 包解决方案的 reprex。

如果我没记错的话,你提供的数据已经在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 创建