将%dopar%用于嵌套的for循环,以找到R

问题描述

我目前正在尝试将美国的所有邮政编码与我拥有的一些邮政编码进行最小距离的匹配。当前的代码如下:

for (i in 1:nrow(Haversine_Zip_Match)){
  # Reset the  nearest distance by every row 
  BestDist <- Inf
  for (j in 1:nrow(merged)){
    # Calculate distance 
    currDist <- dist(merged$LAT[j],Haversine_Zip_Match$LAT[i],merged$LONG[j],Haversine_Zip_Match$LONG[i])
    
    # There are some NA values for long/lat,if (is.na(currDist)){
      currDist <- Inf
    }
    
    # Update best matching result
    if (currDist < BestDist){
      BestDist = currDist
      Haversine_Zip_Match$haversineMatch[i] = merged$ZIP_CD[j]
    }
  }
}

dist是我定义的用于计算距离的函数。但是“ Haversine_Zip_Match”具有40,000行,“ Merged”具有30,000行。总共有超过10亿次计算。有没有办法使其更快?我目前正在考虑使用%dopar%加快该过程。任何想法都会有所帮助,谢谢!

解决方法

您可以尝试减少计算数量,而不是尝试并行化。
通常,邮政编码数据库定义邮政编码周围的最小/最大纬度和经度。
如果没有此信息,则可以在每个邮政编码周围定义一个框,该框要足够大以使邮政编码框区域重叠。
在下面的示例中,我将this邮政编码.rda与43689代码一起使用。

library(data.table)
library(geosphere)
points <- setDT(zipcode)[,.(zip,latitude,longitude)][!is.na(latitude)&!is.na(longitude)]
zipDB <- setDT(zipcode)[,longitude,latmin,latmax,lonmin,lonmax)][!is.na(latitude)&!is.na(longitude)]

# full cross product :
nrow(points) * nrow(zipDB)
#[1] 1908728721

# Area limited cross product
cross <- zipDB[points,.(i.zip,i.latitude,i.longitude,zip,longitude),on = .(latmin <= latitude,lonmin <= longitude,latmax>=latitude,lonmax>=longitude)]
nrow(cross)
#[1] 18501135

# Find zip codes nearest to a point
cross[,dist = distHaversine(cbind(i.longitude,i.latitude),cbind(longitude,latitude)))][dist==min(dist),.(dist),by=.(i.zip,zip)]

当我们将邮政编码数据库与其自身进行比较时,我们可以期望得到完全相同的点数,但是事实并非如此,因为某些邮政编码(例如00210、00211等)具有相同的坐标,所以我们得到了它们的所有组合。

这在我的平板电脑上需要20秒钟。

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...