簡體   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