繁体   English   中英

计算不同数据帧中点之间的距离

[英]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"))

现在我想关联AB以便我可以询问最终问题,如果A$Name==B$Name ,使用相应的lat长数据,它们之间的距离是多少。

我还应该注意到,我不能做一个直接的欧几里德距离,因为这些点出现在水中,它们之间的路径距离需要在水中(或由某个区域限定)。 任何帮助也将受到赞赏。

为了计算经/纬度点之间的距离,你可以使用distm从功能geosphere包。 在此函数中,您可以使用几个公式来计算距离: distCosinedistHaversinedistVincentySpheredistVincentyEllipsoid 最后一个被认为是最准确的一个(根据包裹作者)。

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合并AB (要合并,我们需要一个key集,我已经方便地完成了),然后使用相应的xy坐标来计算(欧几里德)距离。 这样做很简单:

A[B,distance:=sqrt(x^2+y^2)]

您寻找的距离现在存储在列distance下的data.table A 如果你不想存储距离,只想要输出,你可以这样做: A[B,sqrt(x^2+y^2)]

如果AB已经存储为data.frame ,那么从头开始,它并不复杂:

setDT(A,key="Name")[setDT(B,key="Name"),distance:=sqrt(x^2+y^2)]

我们使用方便的setDT函数通过引用AB (内联)转换为data.table ,同时将该key声明为两个*的Name

*设置B的密钥可能不是绝对必要的,但我认为这样做是好的做法。 此外, setDTkey选项目前仅在data.table1.9.5+ )的开发版本中data.table ; 使用CRAN版本,使用setkey(setDT(A),Name)等。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM