【问题标题】:Dissimilarity between rows of two matrices两个矩阵的行之间的差异
【发布时间】:2016-10-17 16:50:22
【问题描述】:

我想计算两个矩阵的每对行的布雷-柯蒂斯距离。

到目前为止,我有一个for-loop,但解决方案根本不是最优的。

这是我想要执行的示例:

a <- matrix(runif(30), 3, 10)
b <- matrix(runif(30), 3, 10)
library(vegan)

d <- data.frame("bray" = 0)

for (i in 1:nrow(a)){
  d[i, "bray"] <- vegdist(rbind(a[i, ], b[i, ]), method = "bray")
}

有没有快速的方法来实现这个操作?

【问题讨论】:

  • 您可以查看非 for 循环解决方案,例如库 purrr 中的 map 函数,但是当您正确标注 d 时,您已经看到了巨大的改进......所以 d &lt;- data.frame(bray=rep(0,nrow(a))) .这样它就不会每次都打开得越来越多

标签: r matrix


【解决方案1】:

您可能会使用诸如 lapply

之类的应用功能获得一些改进
require(dplyr)
require(vegan)

a <- matrix(runif(30), 30000, 10)
b <- matrix(runif(30), 30000, 10)

system.time(
  TMP <- bind_rows(lapply(1:nrow(a),function(y){data.frame(Bray=as.numeric(vegdist(x=rbind(a[y, ], b[y, ]),method="bray")))}))

)

  user  system elapsed 
  5.124   0.000   5.126 

d <- data.frame("bray" = 0)
system.time(
  for (i in 1:nrow(a)){
    d[i, "bray"] <- vegdist(rbind(a[i, ], b[i, ]), method = "bray")
  }
)

 user  system elapsed
 12.588   0.000  12.590

【讨论】:

    【解决方案2】:

    这是一个相对较快的解决方案:

    library(microbenchmark)
    library(vegan)
    a <- matrix(runif(30), 3, 10)
    b <- matrix(runif(30), 3, 10)
    
    f1 <- function(a,b){
        m <- matrix(0, nrow(a)*2, ncol(a))
        m[c(T,F),] <- a
        m[c(F,T),] <- b
        v <- as.matrix(vegdist(m, method = "bray"))
        data.frame(bray=diag(v[-1,])[c(T,F)])
    }
    f2 <- function(a,b){
        d <- data.frame("bray" = 0)
        for (i in 1:nrow(a))
            d[i, "bray"] <- vegdist(rbind(a[i, ], b[i, ]), method = "bray")
        d
    }
    
    all.equal(f1(a,b), f2(a,b))
    # [1] TRUE
    
    microbenchmark(f1(a,b), f2(a,b))
    
    # Unit: microseconds
         # expr     min       lq     mean   median      uq      max neval
     # f1(a, b) 422.597 441.8445 474.2917 452.3235 487.611  744.248   100
     # f2(a, b) 835.782 855.4590 916.9314 873.6370 942.715 1303.718   100
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多