2014-02-24 67 views
18

我想弄清楚我的数据集中的某些特定点是如何隔离的。我使用两种方法确定隔离度,最近邻居的距离以及给定半径内相邻站点的数量。我所有的坐标都在纬度和经度R - 在给定的半径内找到最近的邻近点和邻居数,坐标经纬度为

这是我的数据是这样的:

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         

我想把最近邻池的名字在列的邻居,它的纬度和长在正。 lat和n.long,n.distance中两个池塘之间的距离以及每个相应列中的面积,冠层和平均深度。

其次,我想把目标池塘1500m范围内的池塘数量设置为半径1500。

有没有人知道一个函数或包能够帮助我计算出我想要的距离/数字?如果这是个问题,输入我需要的其他数据并不难,但最近邻居的名字和距离以及1500米内的池塘数量是我真正需要帮助的。

谢谢。

回答

27

最佳选择是使用库sprgeos,它们使您能够构建空间类并执行地理处理。

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) 
之间成对的距离找到第二最短距离(最近距离是点到自身,因此使用第二短)

min.d <- apply(d, 1, function(x) order(x, decreasing=F)[2]) 

构造新的数据帧与所需的变量

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 

这应该提供更好的结果,如果点分散在全球并且坐标是度数

+0

非常感谢。你建议的库正是我需要的! – user2934942

+0

这是一些非常丰富和可读的代码,谢谢!然而,我无法将它调整为稍微不同的用例:我需要找到两个不同数据集之间的最近点(我有一个推文数据集,并且我需要距每个推文最近的城市)。我应该改变什么? – jesusiniesta

+0

函数'gDistance'可以带两个参数 - 在你的情况下是推文和城市。由此产生的矩阵应该有两个之间的所有成对距离(但要注意,如果你有成千上万的点,这可能是太多的个人电脑) – Zbynek

0

该解决方案由@Zbyne K是相当不错的,但是如果你正在寻找像我这样在两公里内的两个邻居之间的距离,我提出这个解决方案。

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") 

如果你的坐标是长和长,你最终会得到以公里为单位的距离。

任何建议,使其更好?

+0

不需要自己修复它,已经有'geosphere'包 - https ://cran.r-project.org/web/packages/geosphere/geosphere.pdf – Zbynek

+0

该软件包中的哪一个函数计算以公里为单位的欧几里得距离? –

+0

我觉得'distm',你可以选择精确的公式 - 默认是Haversine,但是有更多的选择(参见手册) – Zbynek