在R

时间:2015-10-23 12:15:37

标签: r matrix foreach parallel-processing geospatial

我有一个坐标列表(cc),我希望使用" distVincentyEllipsoid"成为距离矩阵。功能在R。

缓慢的方式是:

distmat <- apply(cc, 1, FUN=function(X) distVincentyEllipsoid(X, cc))

然而,对于大约5000个坐标,这需要4,227秒。由于我的最终矩阵是对称的,我只想计算下三角;所以我的想法是:1)在嵌套的foreach循环中创建成对组合,然后2)将其重塑为我需要的矩阵:

 X <- diag(p) 
    X[upper.tri(X, diag=TRUE)] <- elements 
    X <- X + t(X) - diag(diag(X)

我无法完成第一部分工作,例如:下面我尝试了创建我想要的顺序:

library(foreach)
library(doParallel)

cl <- makeCluster(detectCores())
registerDoParallel(cl)

# Create SAMPLE data-frame from 1 to 100 
sample_df <- data.frame(seq(1:100))
names(sample_df) <- c("id")

# Output should have 100*99/2 rows = 4950
output <- matrix(ncol=2,nrow=nrow(sample_df)*(nrow(sample_df)-1)/2)

do_par_combos <- foreach(a=1:(nrow(sample_df))) %:%
                    foreach(b=(a+1):(nrow(sample_df)-1)) %dopar% {
                      # At the moment just create two columns with the IDs
                      # Expecting: [1,2],[1,3],..,[1,100],[2,3],.
                      output[counter,1] <- sample_df[a,c("id")]
                      output[counter,2] <- sample_df[b,c("id")]
                      counter = counter + 1
                    }


# RUN
do_par_combos
# Close processes
stopCluster(cl = cl)

我的输出只是满满的。我想这是因为我不能并行运行一个计数器,因为它会被覆盖?我很好奇:

  1. 使这个并行for-each循环工作(即使它不是创建对称vincenty距离矩阵的最快方法)

  2. 了解创建对称vincenty距离矩阵的最快方法。

1 个答案:

答案 0 :(得分:0)

您可以使用distm包中的geosphere函数创建距离矩阵:

library(geosphere)
cc <- rbind(c(0,0),
            c(90,90),
            c(10,10),
            c(-120,-45),
            c(45, 45))

dist_mat <- distm(cc, fun = distVincentyEllipsoid)
dist_mat
##          [,1]     [,2]     [,3]     [,4]     [,5]
## [1,]        0 10001966  1565109 12317881  6662473
## [2,] 10001966        0  8896111 14986910  5017021
## [3,]  1565109  8896111        0 13879039  5122094
## [4,] 12317881 14986910 13879039        0 18839623
## [5,]  6662473  5017021  5122094 18839623        0

as.dist(dist_mat, diag = TRUE)
##          1        2        3        4        5
## 1        0                                    
## 2 10001966        0                           
## 3  1565109  8896111        0                  
## 4 12317881 14986910 13879039        0         
## 5  6662473  5017021  5122094 18839623        0