簡體   English   中英

對於表中的每個觀測值,根據緯度和經度 (R) 計算 x 米內表中其他觀測值的數量

[英]For each observation in a table, count number of other observations in table within x metres based on latitude and longitude (R)

我有一個包含經度和緯度的位置數據框,它看起來像:

set.seed(211)
latitude <-runif(5000, min=50, max=55)
longitude <- runif(5000, min=-2, max=0)
location_id <- seq(1,5000)

reprex <- data.frame(location_id, latitude, longitude)

對於每個 location_id,我需要計算列表中距離該位置 10 英里(約 16000 米)范圍內的其他位置的數量。

我正在考慮在某種 for 循環(或者可能是應用函數)中為此使用 geosphere::distGeo(),但我無法弄清楚如何對其進行編碼,以便將列表中的所有其他項目與當前項目進行比較item 並計算在某個閾值內的數量,記錄該值,然后移至下一行。

有誰知道這個怎么寫?

distGeo函數可以做到,但您需要一個循環。 請注意,坐標的第一列必須是經度。

lst <- vector(50, mode="list")

for(i in 1:50) {
    dist <- distGeo(p1=reprex[i,c(3,2)], p2=reprex[-i,c(3,2)])
    lst[[i]] <- sum(dist<16000)
}

reprex$n <- unlist(lst)

table(unlist(lst))
 0  1  2 
34 10  6

因此,50 個點中的 34 個在 10 英里(約 16,000 米)范圍內沒有任何其他點,10 個只有 1,6 個有 2。

fieldsrdist.earth函數似乎對此很有用,例如:

library(fields)
dist.matrix <- rdist.earth(reprex[-1])
colSums(dist.matrix<10)

在這種情況下唯一的技巧是在邏輯矩陣上使用colSums來計算TRUE值的數量。

請注意,miles 是默認值,km 可以與參數miles=FALSE

將循環隱藏在(仍然很慢) apply和解開經度和緯度(它們通常是相反的)中,您可以嘗試類似的方法

set.seed(211)
latitude <-runif(5000, min=50, max=55)
longitude <- runif(5000, min=-2, max=0)
location_id <- seq(1, 5000)
reprex <- data.frame(location_id, latitude, longitude)

library(geosphere)
within10m <- function(p1, p2, dist=16000){
  sum(geosphere::distGeo(p1, p2) <= dist)
  }
matpoints <- as.matrix(reprex[, 3:2])
reprex$neighbours <- 
  apply(matpoints, 1, within10m, p2=matpoints) - 1
head(reprex) 
#   location_id latitude  longitude neighbours
# 1           1 51.17399 -1.1489713         48
# 2           2 54.52623 -1.8554624         39
# 3           3 54.84852 -0.3014742         56
# 4           4 51.72104 -1.8644226         50
# 5           5 51.32793 -0.7417923         56
# 6           6 50.07346 -0.8939857         36

最終我在這里使用了答案,因為它非常優雅且避免了循環: 計算特定半徑內的點數

我使用了代碼:

library(geosphere) # for distHaversine() and distm() functions

reprex <- cbind(reprex, # appends to the dataset... 
                     count_nearby=rowSums( # ... a column which counts the rows in the dataset...
                       distm (reprex[,3:2], fun = distHaversine) # ... where the distance between current and other rows...
                       <= 16000)-1 # ... is less than 16000 metres. Take one away because it counts itself!
                ) #close the cbind brackets!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM