使用带有循环的不同长度的不同数据帧中的纬度和经度数据计算距离

问题描述

我有2个不同长度的数据帧,每个数据帧都有一个经度和纬度坐标。我想通过计算经纬度之间的距离来连接两个数据框。

为简单起见,数据帧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       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

在发布此内容之前,我咨询了几个Stack Overflow线程(包括this oneThis Medium post,但是我不确定如何进行循环,尤其是由于列表的长度不同。

谢谢!

解决方法

我认为您可以在这里非常简洁地使用outer

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

数据:

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")
,

这是使用两个软件包的解决方案:sftidyverse。第一个用于将数据转换为简单特征并计算距离;同时,第二个用于将数据放入所需的格式。

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")

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...