![](/img/trans.png)
[英]Calculating maximum distance between location points in two different grouped data frames
[英]Calculating the distance between points in different data frames
我试图找到两个不同数据帧中点之间的距离,因为它们在其中一列中具有相同的值。
我认为第一步是加入或关联两个数据帧中的数据。 例如,有数据框A和B,它们都包含纬度/经度信息,并且它们共享列Name
。 请注意,对于给定的名称,每个数据帧中的纬度/经度信息是不同的。 这就是为什么我想计算它们之间的距离。
我设想最终的函数就像A$Name=B$Name
然后使用它们相应的lat / long数据来计算它们之间的距离。
有什么想法吗?
示例数据:
A <- data.frame(Lat=1:4,Long=1:4,Name=c("a","b","c","d"))
B <- data.frame(Lat=5:8,Long=5:8,Name=c("a","b","c","d"))
现在我想关联A
和B
以便我可以询问最终问题,如果A$Name==B$Name
,使用相应的lat长数据,它们之间的距离是多少。
我还应该注意到,我不能做一个直接的欧几里德距离,因为这些点出现在水中,它们之间的路径距离需要在水中(或由某个区域限定)。 任何帮助也将受到赞赏。
为了计算经/纬度点之间的距离,你可以使用distm
从功能geosphere
包。 在此函数中,您可以使用几个公式来计算距离: distCosine
, distHaversine
, distVincentySphere
和distVincentyEllipsoid
。 最后一个被认为是最准确的一个(根据包裹作者)。
library(geosphere)
A <- data.frame(Lat=1:4, Long=1:4, Name=c("a","b","c","d"))
B <- data.frame(Lat=5:8, Long=5:8, Name=c("a","b","c","d"))
A$distance <- distVincentyEllipsoid(A[,c('Long','Lat')], B[,c('Long','Lat')])
这给了:
> A
Lat Long Name distance
1 1 1 a 627129.5
2 2 2 b 626801.7
3 3 3 c 626380.6
4 4 4 d 625866.6
请注意,您必须按照第一个经度和纬度的顺序包含纬度/经度列。
虽然这在这个简单的例子中完美地起作用,但是在名称不是相同顺序的较大数据集中,这将导致问题。 在这种情况下,您可以使用data.table
并设置键,以便您可以匹配点并计算距离(正如@MichaelChirico在他的回答中所做的那样):
library(data.table)
A <- data.table(Lat=1:4, Long=1:4, Name=c("a","b","c","d"), key="Name")
B <- data.table(Lat=8:5, Long=8:5, Name=c("d","c","b","a"), key="Name")
A[B,distance:=distVincentyEllipsoid(A[,.(Long,Lat)], B[,.(Long,Lat)])]
正如您所看到的,这给出了与前一个方法相同的正确(即相同)结果:
> A
Lat Long Name distance
1: 1 1 a 627129.5
2: 2 2 b 626801.7
3: 3 3 c 626380.6
4: 4 4 d 625866.6
要查看key="Name"
作用,请比较以下两个数据表:
B1 <- data.table(Lat=8:5, Long=8:5, Name=c("d","c","b","a"), key="Name")
B2 <- data.table(Lat=8:5, Long=8:5, Name=c("d","c","b","a"))
有关更详细的示例,请参阅此答案 。
如果没有可重复的示例,我所能做的就是为您提供一般解决方案。
我喜欢data.table
,这里的语法看起来很简单。 有关包装的更多信息,请查看“ 入门”插图。
我将创建两个data.table
匹配您的一般描述的data.table
:
library(data.table)
set.seed(1734)
A<-data.table(Name=1:10,x=rnorm(10),key="Name")
B<-data.table(Name=1:10,y=rnorm(10),key="Name")
现在,我们想要通过Name
合并A
和B
(要合并,我们需要一个key
集,我已经方便地完成了),然后使用相应的x
和y
坐标来计算(欧几里德)距离。 这样做很简单:
A[B,distance:=sqrt(x^2+y^2)]
您寻找的距离现在存储在列distance
下的data.table
A
如果你不想存储距离,只想要输出,你可以这样做: A[B,sqrt(x^2+y^2)]
。
如果A
和B
已经存储为data.frame
,那么从头开始,它并不复杂:
setDT(A,key="Name")[setDT(B,key="Name"),distance:=sqrt(x^2+y^2)]
我们使用方便的setDT
函数通过引用将A
和B
(内联)转换为data.table
,同时将该key
声明为两个*的Name
。
*设置B
的密钥可能不是绝对必要的,但我认为这样做是好的做法。 此外, setDT
的key
选项目前仅在data.table
( 1.9.5+
)的开发版本中data.table
; 使用CRAN版本,使用setkey(setDT(A),Name)
等。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.