“对于这种for循环,是否有更快的替代方法,我需要在每行中将每行与其他行相乘一次?”

时间:2019-05-24 15:52:41

标签: r loops

这个for循环要花很长时间才能运行?

for (i in 1:nrow(petrolStations)) {
k<-i+1
if(k<=nrow(petrolStations)) {
for(j in k:nrow(petrolStations)) {
distancesToStation[i,j] <- ,        
as.data.frame(a s.numeric(distm(petrolStations[i, c("lon", "lat")],
petrolStations[j, c("lon", "lat")], fun = distHaversine)/1000))}
}}

1 个答案:

答案 0 :(得分:0)

我将使用自己的示例数据:

set.seed(2)
y <- data.frame(lon = rnorm(10, mean = -114.4069597, sd = 0.0001),
                lat = rnorm(10, mean = 43.660648, sd = 0.0002) )

我猜您执行双循环的原因是,您不必计算每个距离两次。如果通常使用基本dist函数,它将提供下三角输出,而不计算上三角。下面的方法模仿了这种行为。

nr <- nrow(y)
out <- sapply(seq_len(nr), function(i) {
  if (i == nr) return(c(rep(NA_real_, i - 1), 0))
  c(rep(NA_real_, i - 1), 0,
    geosphere::distHaversine(y[i,,drop = FALSE],
                             y[(i+1):nr,,drop = FALSE]))
})
out
#         [,1]   [,2]  [,3]  [,4]  [,5]  [,6]  [,7]   [,8]  [,9] [,10]
#  [1,]  0.000     NA    NA    NA    NA    NA    NA     NA    NA    NA
#  [2,] 15.285  0.000    NA    NA    NA    NA    NA     NA    NA    NA
#  [3,] 26.943 32.620  0.00    NA    NA    NA    NA     NA    NA    NA
#  [4,] 32.500 46.234 26.20  0.00    NA    NA    NA     NA    NA    NA
#  [5,] 31.085 17.949 50.25 63.39  0.00    NA    NA     NA    NA    NA
#  [6,] 61.315 73.312 44.29 30.08 91.15  0.00    NA     NA    NA    NA
#  [7,] 16.503  4.798 29.18 45.20 21.10 71.17  0.00     NA    NA    NA
#  [8,] 10.014 21.336 17.54 25.00 38.90 52.34 20.26  0.000    NA    NA
#  [9,] 26.722 14.509 31.46 52.13 23.87 75.49 10.71 28.178  0.00    NA
# [10,]  6.114 12.508 23.04 33.73 30.06 61.12 12.05  8.864 21.43     0

任意验证:

geosphere::distHaversine(y[8,], y[2,])
# [1] 21.33617

这比您的代码快,因为它利用矢量化计算:geosphere::distHaversine可以一次计算多个距离:

  • 点之间(如果缺少第二个参数);
  • p1中的所有点与p2中的相应点之间({{1}和p1的行数相同);或
  • 正如我在上面所做的那样,单点对多点。

p2是要确保上三角是c(rep(NA_real_, i - 1), 0, ...),对角线是0。第一个条件(NA)是作弊项,以确保我们有一个方矩阵,最后一列是全{i==nr和0。

如果您还需要填充上三角:

NA