尝试创建一个函数,通过最近的gps坐标连接两个数据集

时间:2016-05-05 02:44:13

标签: r for-loop gps spatial sp

我正在尝试合并两个包含GPS坐标的数据集,以便我留下一个带有两个数据集变量的数据集。我正在尝试使用一个函数来实现这一目标。问题是来自两个数据集的GPS坐标不完全匹配。因此,任务是通过找到最接近的gps坐标配对,将一个数据集的变量与其他数据集的变量进行匹配。

我已经成功使用模糊连接包,但只能获得部分匹配(~75%)。有了下面的功能,我希望获得更高程度的匹配。一个数据集比另一个数据集短,因此这里的想法是使用两个for循环,每个for循环遍历每个数据集。

建立“锚”(两个数据集的第一次观察之间的距离),使得如果两个点之间的距离小于锚,则新的(较短的)距离成为新的锚。 for循环继续,直到找到最短距离,并且来自两个数据集的变量都附加到新数据集的末尾,此处称为pairedData。只要使用最短的数据集(6314行),我就应该留下一个数据集,并从两个数据集中获取数据。

我认为该函数应该可以工作,但是rbind()非常慢,而且我在实现rbindlist()时遇到了麻烦。关于如何实现这一目标的任何想法?

combineGPS <- function(harvest,planting) {
require(sp)
require(data.table)
longH <- harvest$long
latH <- harvest$lat
longP <- planting$long
latP <- planting$lat
rowsH <- nrow(harvest)
rowsP <- nrow(planting)
harvestCoords <- cbind(longH,latH)
harvestPoints <- SpatialPoints(harvestCoords)
plantingCoords <- cbind(longP,latP)
plantingPoints <- SpatialPoints(plantingCoords)

#planting数据短于收获数据

#need取每行种植数据(6314)并找到最接近的收获数据点(16626),然后附上

anchor <- spDistsN1(plantingPoints[1,],harvestPoints[1,],longlat=FALSE)
pairedData <- data.frame(long=numeric(),
               lat=numeric(), 
               variety=factor(), 
               seedling_rate=numeric(),
               seed_spacing=numeric(),
               speed=numeric(),
               yield=numeric(),
               stringsAsFactors=FALSE) 

for (p in 1:rowsP){
     for (h in 1:rowsH){

   if(spDistsN1(plantingPoints[p,],harvestPoints[h,],longlat=FALSE) <= anchor){
    anchor <- spDistsN1(plantingPoints[p,],harvestPoints[h,],longlat=FALSE)
    pairedData[p,]<-c(planting[p,]$long, planting[p,]$lat, planting[p,]$variety, planting[p,]$seedling_rate, planting[p,]$seed_spacing, planting[p,]$speed, harvest[h,]$yield)
   }    

       }
   }
  return(pairedData)
}
doesItWork=combineGPS(harvest,planting)
doesItWork

2 个答案:

答案 0 :(得分:0)

如果我正确理解您的问题,我不确定为什么您需要对收获数据进行for循环。函数spDistsN1将返回到指定点的距离矩阵。我认为您应该将收获数据用作pts,并将种植数据用作此函数的pt输入,然后找到距每个pt最短距离的索引。仅覆盖种植数据。会节省很多时间。此外,请勿在{{1​​}}中指定longlat,因为您的数据为spDistsN1且函数说明不为这些对象指定。

示例循环:

SpatialPoints

如果您正在寻找,请告诉我。

此外,您可以使用种植数据初始化pairedData数据框,并且在for (p in 1:rowsP){ #Get the distance from the pth planting point to all of the havest points Dists <- spDistsN1(pts = harvestPoints, pt = plantingPoints[p,]) #Find the index of the nearest harvest point to p. This is the minimum of Dists. (Note that there may be more than one minimum) NearestHarvest <- which(Dists == min(Dists)) #Add information to the paired data pairedData[p,]<-c(planting[p,]$long, planting[p,]$lat, planting[p,]$variety, planting[p,]$seedling_rate, planting[p,]$seed_spacing, planting[p,]$speed, harvest[NearestHarvest,]$yield) } 循环中仅将收获产量数据添加到pairedData数据框。这也可以为你节省一些时间。

答案 1 :(得分:0)

您需要将收获文件(16626)中的每一行映射到种植(6314)文件中的一行,而不是相反。下图是xy平面上的收获和植物gps坐标图。红点是收割机点。

Planter Harvester GPS

精密农用机是一种多排播种机&amp;收割机。 gps设备安装在机器内部。即每个gps点指的是许多行的作物。在这种情况下,与每次行程的收割机相比,播种机覆盖2X行。这解释了为什么收获文件有~2X +数据点。

基本方法是强力搜索,因为gps坐标不会在文件之间重叠。我通过将整个场分割成更小的均匀网格并将搜索限制到最近的相邻网格,在R和Python中解决了这个问题。在效率方面,解决需要3-4分钟,种植和收获点之间的距离平均约为3米,这是合理的。

您可以在Github

上找到该代码