![](/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.