如何用向量运算替换double for循环

时间:2015-12-09 01:43:50

标签: r performance for-loop vectorization

我正在尝试创建自定义分发函数(基于hasrsine)。现在我的原型是一个双for循环。我已经浏览了矢量化操作,我仍然在学习(对R来说很新),所以目前尚不清楚如何清理它。最后,我想要一个NxN矩阵,用于比较地球上各点之间的距离。这是我现在的测试数据:

coord
     Latitude   Longitude
1    16.34577    6.303545
2    12.49475   28.626396
3    27.79462   60.032495
4    44.42699  110.114216
5   -69.85409   87.946878

邪恶的双for - 循环:

for (i in 1:dim(coord)[1]){
  for(j in 1:dim(coord)[1]) # for each column {
    mymat[i,j] = coord[i,1]*coord[j,2]     # custom function for future
  }
} 

结果:

           X1         X2         X3        X4        X5
1   103.03629   467.9204   981.2773  1799.902  1437.559
2    78.76122   357.6796   750.0910  1375.850  1098.874
3   175.20461   795.6596  1668.5801  3060.582  2444.450
4   280.04755  1271.7847  2667.0632  4892.043  3907.215
5  -440.32840 -1999.6708 -4193.5152 -7691.928 -6143.449

当然,对于5个样品,没问题。但我有一个100k的清单。

我在搜索后确实看到了一个功能

custom.dist <- function(x, my.dist) {
  mat <- sapply(x, function(x.1) sapply(x, function(x.2) my.dist(x.1, x.2)))
  as.dist(mat)
}

但我不明白发生了什么,也无法让它发挥作用,即使是像x*y这样的虚拟函数

1 个答案:

答案 0 :(得分:4)

看起来你只想要外部产品。有一个功能 - 方便地命名为outer。现在outer可以应用除乘法以外的函数,但默认值是乘法,因此我们不需要明确指定它。

> coord <- cbind(1:5, 2:6)
> coord
     [,1] [,2]
[1,]    1    2
[2,]    2    3
[3,]    3    4
[4,]    4    5
[5,]    5    6
> outer(coord[,1], coord[,2])
     [,1] [,2] [,3] [,4] [,5]
[1,]    2    3    4    5    6
[2,]    4    6    8   10   12
[3,]    6    9   12   15   18
[4,]    8   12   16   20   24
[5,]   10   15   20   25   30

请注意,此方法也很容易概括为其他二进制函数

> outer(coord[,1], coord[,2], FUN = paste0)
     [,1] [,2] [,3] [,4] [,5]
[1,] "12" "13" "14" "15" "16"
[2,] "22" "23" "24" "25" "26"
[3,] "32" "33" "34" "35" "36"
[4,] "42" "43" "44" "45" "46"
[5,] "52" "53" "54" "55" "56"