R 使用不同长度的不同数据帧中的纬度和经度数据,使用loop计算距离
我有两个不同长度的数据帧,每个数据帧都有一个经度和纬度坐标。我想通过计算lat/long点之间的距离来连接两个数据帧 为简单起见,数据帧A(起点)具有以下结构R 使用不同长度的不同数据帧中的纬度和经度数据,使用loop计算距离,r,loops,distance,latitude-longitude,geosphere,R,Loops,Distance,Latitude Longitude,Geosphere,我有两个不同长度的数据帧,每个数据帧都有一个经度和纬度坐标。我想通过计算lat/long点之间的距离来连接两个数据帧 为简单起见,数据帧A(起点)具有以下结构 ID long lat 1 -89.92702 44.19367 2 -89.92525 44.19654 3 -89.92365 44.19756 4 -89.91949 44.19848 5 -89.91359 44.19818 数据帧B(端点)具有类似的结构,但更短 ID LAT
ID long lat
1 -89.92702 44.19367
2 -89.92525 44.19654
3 -89.92365 44.19756
4 -89.91949 44.19848
5 -89.91359 44.19818
数据帧B(端点)具有类似的结构,但更短
ID LAT LON
1 43.06519 -87.91446
2 43.14490 -88.07172
3 43.08969 -87.91202
我想计算每个点之间的距离,这样我将以一个数据帧结束,合并为a,该数据帧具有A1和B1、A1和B2、A1和B3之间的距离。此外,对于A$ID中A的所有值和B$ID的所有值,应重复此操作
A$ID B$ID
1 1
2 2
3 3
4
5
在发布这篇文章之前,我咨询了几个堆栈溢出线程(包括和),但我不确定如何处理循环,特别是因为列表的长度不同
谢谢!这是一个使用两个包的解决方案:
sf
和tidyverse
。第一个包用于将数据转换为简单的要素并计算距离;第二个包用于将数据转换为所需的格式
library(tidyverse)
library(sf)
# Transform data into simple features
sfA <- st_as_sf(A, coords = c("long","lat"))
sfB <- st_as_sf(B, coords = c("LON","LAT"))
# Calculate distance between all entries of sf1 and sf2
distances <- st_distance(sfA, sfB, by_element = F)
# Set colnames for distances matrix
colnames(distances) <- paste0("B",1:3)
# Put the results in the desired format
# Transform distances matrix into a tibble
as_tibble(distances) %>%
# Get row names and add them as a column
rownames_to_column() %>%
# Set ID as the column name for the row numbers
rename("ID" = "rowname") %>%
# Transform ID to numeric
mutate_at(vars(ID), as.numeric) %>%
# Join with the original A data frame
right_join(A, by = "ID") %>%
# Change the order of columns
select(ID, long, lat, everything()) %>%
# Put data into long format
pivot_longer(cols = starts_with("B"),
names_to = "B_ID",
names_pattern = "B(\\d)",
values_to = "distance")
库(tidyverse)
图书馆(sf)
#将数据转换为简单特征
sfA%
#与原始数据帧连接
右键联接(A,by=“ID”)%>%
#更改列的顺序
选择(ID、long、lat、everything())%>%
#将数据转换为长格式
枢轴长度(cols=以“B”开头),
name_to=“B_ID”,
名称\u pattern=“B(\\d)”,
值_to=“距离”)
我认为您可以在这里非常简洁地使用外部
library(geosphere)
d <- outer(1:nrow(A), 1:nrow(B), Vectorize(function(x, y) distm(A[x, 2:3], B[y, 3:2])))
cbind(A, `colnames<-`(d, paste0("B", seq(nrow(B)))))
# ID long lat B1 B2 B3
# 1 1 -89.92702 44.19367 205173.6 189641.7 203652.9
# 2 2 -89.92525 44.19654 205252.6 189722.5 203728.1
# 3 3 -89.92365 44.19756 205219.0 189689.8 203692.6
# 4 4 -89.91949 44.19848 205015.6 189488.0 203486.2
# 5 5 -89.91359 44.19818 204620.0 189093.8 203087.6
库(geosphere)
D
A <- read.table(header=T, text="ID long lat
1 -89.92702 44.19367
2 -89.92525 44.19654
3 -89.92365 44.19756
4 -89.91949 44.19848
5 -89.91359 44.19818")
B <- read.table(header=T, text="ID LAT LON
1 43.06519 -87.91446
2 43.14490 -88.07172
3 43.08969 -87.91202")