【问题标题】:Is there any way I can optimize this R code?有什么办法可以优化这个 R 代码吗?
【发布时间】:2020-10-12 21:43:40
【问题描述】:

这是我试图在 rstudio 中运行的代码。我知道迭代太长了。有没有最佳/更快的方法来做到这一点?我已经被困了 4 个多小时,而且似乎不会很快完成。

我正在尝试在 415 个城市和 3680126 个纪念碑之间建立一个距离矩阵。为了优化,我只是将那些古迹与同一个国家的城市进行比较。

for(x in 1:3680126){
  for(y in 1:415){
    if(list2_cities$Country[y]==list1_POI$Country[x]){
      distance_matrix [x,y] <- ({POI$Longitude[x]-cities$Longitude[y]}^2)+({POI$Latitude[x]-cities$Latitude[y]}^2)
    }
    else{
      distance_matrix [x,y] <- 0
    }
  }
}

【问题讨论】:

  • 如果这些真的是地理空间意义上的经纬度,那么我要回答的第一个问题是:不要这样做。勾股定理在笛卡尔空间中运行良好,但地理坐标不是笛卡尔坐标。即使您不关心距离计算的正确单位,在地球上的大部分地区,1 度纬度和 1 度经度也有很大的不同。我建议使用geosphere::dist* 函数之一,具体取决于您对精度的需求。
  • @r2evans 这是有道理的。我正在使用 geosphere,但它也需要很长时间。有什么办法可以在更短的时间内完成?
  • 您的两个循环正在执行 15 亿次迭代,使用任何方法都需要一些时间。托马斯在下面的回答是一个巨大的进步。我建议按国家/地区拆分您的数据框,然后在较小的数据集上使用distm 函数。这将通过避免计算跨越国界的距离来提高性能。

标签: r dataframe matrix optimization


【解决方案1】:

也许你可以试试 distm 来自包 geosphere

library(geosphere)
d <- distm(list1_POI[c("Longitude","Latitude")],list2_cities[c("Longitude","Latitude")])
m <- +(outer(list1_POI$Country,list2_cities$Country,`==`))
res <- d*m

在哪里

  • distm 部分给出了两个城市之间的所有配对距离
  • outer 部分提供掩码,以便将不匹配城市的值设置为 0

如果你想要的矩阵是稀疏的,这里有另一个选项

common <- intersect(list1_POI$Country,list2_cities$Country)
rl <- match(common,list1_POI$Country)
cl <- match(common,list2_cities$Country)
d <- diag(distm(list1_POI[rl,c("Longitude","Latitude")],list2_cities[cl,c("Longitude","Latitude")]))
res <- matrix(0,length(list1_POI$Country),length(list1_cities$Country))
res[cbind(rl,cl)] <- d

您只需要定位匹配的城市并计算它们的距离。

【讨论】:

  • 不过,最终,这是为我们知道我们将要丢弃的那些计算距离,对吧?
  • @r2evans 抱歉打错了,谢谢指正!
  • @r2evans 是的,它首先计算所有距离,然后根据不匹配的城市过滤掉值。
猜你喜欢
  • 1970-01-01
  • 2019-02-04
  • 1970-01-01
  • 2023-03-18
  • 2012-01-24
  • 2018-10-30
  • 2012-03-13
  • 1970-01-01
  • 2020-03-05
相关资源
最近更新 更多