R – 在给定半径范围内查找最近邻点和邻点数,坐标为经纬度
我想弄清楚我的数据集中有多less孤立点。 我使用两种方法来确定隔离,最近的邻居的距离以及给定半径内的相邻站点的数量。 我所有的坐标都是经纬度的
这是我的数据看起来像:
pond lat long area canopy avg.depth neighbor n.lat n.long n.distance n.area n.canopy n.depth n.avg.depth radius1500 A10 41.95928 -72.14605 1500 66 60.61538462 AA006 41.96431 -72.121 250 0 57.77777778 Blacksmith 41.95508 -72.123803 361 77 71.3125 Borrow.Pit.1 41.95601 -72.15419 0 0 41.44444444 Borrow.Pit.2 41.95571 -72.15413 0 0 37.7 Borrow.Pit.3 41.95546 -72.15375 0 0 29.22222222 Boulder 41.918223 -72.14978 1392 98 43.53333333
我想把最邻近的一个池塘的名字放在邻居列中,它的纬度和长度分别是n.lat和n.long,两个池塘之间的距离是n.distance,面积,冠层和avg.depth是每个适当的列。
其次,我想把目标池塘1500m范围内的池塘数目放到半径1500以内。
有没有人知道一个函数或包将帮助我计算我想要的距离/数字? 如果这是一个问题,input我所需要的其他数据并不难,但最近邻居的名字和距离,加上1500米以内的池塘数量是我真正需要帮助的。
谢谢。
最佳select是使用库sp
和rgeos
,这使您可以构build空间类和执行地理处理。
library(sp) library(rgeos)
读取数据并将其转换为空间对象:
mydata <- read.delim('d:/temp/testfile.txt', header=T) sp.mydata <- mydata coordinates(sp.mydata) <- ~long+lat class(sp.mydata) [1] "SpatialPointsDataFrame" attr(,"package") [1] "sp"
现在计算点之间的配对距离
d <- gDistance(sp.mydata, byid=T)
find第二个最短的距离(最近的距离是指向自身,因此使用第二短的距离)
min.d <- apply(d, 1, function(x) order(x, decreasing=F)[2])
用期望的variables构build新的数据框
newdata <- cbind(mydata, mydata[min.d,], apply(d, 1, function(x) sort(x, decreasing=F)[2])) colnames(newdata) <- c(colnames(mydata), 'neighbor', 'n.lat', 'n.long', 'n.area', 'n.canopy', 'n.avg.depth', 'distance') newdata pond lat long area canopy avg.depth neighbor n.lat n.long n.area n.canopy n.avg.depth 6 A10 41.95928 -72.14605 1500 66 60.61538 Borrow.Pit.3 41.95546 -72.15375 0 0 29.22222 3 AA006 41.96431 -72.12100 250 0 57.77778 Blacksmith 41.95508 -72.12380 361 77 71.31250 2 Blacksmith 41.95508 -72.12380 361 77 71.31250 AA006 41.96431 -72.12100 250 0 57.77778 5 Borrow.Pit.1 41.95601 -72.15419 0 0 41.44444 Borrow.Pit.2 41.95571 -72.15413 0 0 37.70000 4 Borrow.Pit.2 41.95571 -72.15413 0 0 37.70000 Borrow.Pit.1 41.95601 -72.15419 0 0 41.44444 5.1 Borrow.Pit.3 41.95546 -72.15375 0 0 29.22222 Borrow.Pit.2 41.95571 -72.15413 0 0 37.70000 6.1 Boulder 41.91822 -72.14978 1392 98 43.53333 Borrow.Pit.3 41.95546 -72.15375 0 0 29.22222 distance 6 0.0085954872 3 0.0096462277 2 0.0096462277 5 0.0003059412 4 0.0003059412 5.1 0.0004548626 6.1 0.0374480316
编辑:如果坐标以度为单位,并且您想以公里计算距离,请使用软件包geosphere
library(geosphere) d <- distm(sp.mydata) # rest is the same
如果点分散在全球,坐标是度,这应该提供更好的结果
由@Zbynek提出的解决scheme是相当不错的,但如果你正在寻找像我这样的两公里之间的相邻距离之间的距离,我提出这个解决scheme。
earth.dist<-function(lat1,long1,lat2,long2){ rad <- pi/180 a1 <- lat1 * rad a2 <- long1 * rad b1 <- lat2 * rad b2 <- long2 * rad dlat <- b1-a1 dlon<- b2-a2 a <- (sin(dlat/2))^2 +cos(a1)*cos(b1)*(sin(dlon/2))^2 c <- 2*atan2(sqrt(a),sqrt(1-a)) R <- 6378.145 dist <- R *c return(dist) } Dist <- matrix(0,ncol=length(mydata),nrow=length(mydata.sp)) for (i in 1:length(mydata)){ for(j in 1:length(mydata.sp)){ Dist[i,j] <- earth.dist(mydata$lat[i],mydata$long[i],mydata.sp$lat[j],mydata.sp$long[j]) }} DDD <- matrix(0, ncol=5,nrow=ncol(Dist)) ### RECTIFY the nb of col by the number of variable you want for(i in 1:ncol(Dist)){ sub<- sort(Dist[,i])[2] DDD[i,1] <- names(sub) DDD[i,2] <- sub DDD[i,3] <- rownames(Dist)[i] sub_neig_atr <- Coord[Coord$ID==names(sub),] DDD[i,4] <- sub_neig_atr$area DDD[i,5] <- sub_neig_atr$canopy ### Your can add any variable you want here } DDD <- as.data.frame(DDD) names(DDD)<-c("neigboor_ID","distance","pond","n.area","n.canopy") data <- merge(mydata,DDD, by="pond")
如果你的坐标是长和长,你最终会得到一个以公里为单位的距离。
任何build议,使其更好?