【问题标题】:R fast cbind matrix using Rcpp使用 Rcpp 的 R 快速 cbind 矩阵
【发布时间】:2016-05-20 16:19:42
【问题描述】:

R中的cbind在重复调用中相对比较耗时,但它对各种数据类型也很强大。 绑定两个矩阵时,我编写的代码比 cbind 快 3 倍。但是dplyr 包中的bind_cols 仅比cbind 快100 倍。只可惜不能以矩阵为输入。有人可以使下面的代码更快。另外,如何快速绑定稀疏矩阵?这是我使用的代码:

require( Rcpp )

func <- 'NumericMatrix mmult(NumericMatrix a,NumericMatrix b) {
    //the colnumber of first matrix
    int acoln=a.ncol();
    //the colnumber of second matrix
    int bcoln=b.ncol();
    //build a new matrix, the dim is a.nrow() and acoln+bcoln
    NumericMatrix out(a.nrow(),acoln+bcoln) ;
    for (int j = 0; j < acoln + bcoln; j++) {
        if (j < acoln) {
            out(_,j) = a(_,j);
        } else {
            //put the context in the second matrix to the new matrix
            out(_,j) = b(_,j-acoln);
        }
    }
    return out ;
}'

a <- matrix(rep(1,2000*100),2000)
b <- matrix(rep(2,2000*10),2000)

cppFunction(func)

system.time(for (i in seq(1,800)) {mmult(a,b)})
system.time(for (i in seq(1,800)) {cbind(a,b)})
identical(mmult(a,b),cbind(a,b))

【问题讨论】:

    标签: c++ r rcpp cbind


    【解决方案1】:

    从 Romain Francois 的 comment 中借用我之前的 Rcpp 冒险之一的想法,

    func1 <- 'NumericMatrix mmult1(NumericMatrix a, NumericMatrix b) {
      int acoln = a.ncol();
      int bcoln = b.ncol();
      NumericMatrix out = no_init_matrix(a.nrow(), acoln + bcoln);
      for (int j = 0; j < acoln + bcoln; j++) {
        if (j < acoln) {
          out(_, j) = a(_, j);
        } else {
          out(_, j) = b(_, j - acoln);
        }
      }
      return out;
    }'
    
    cppFunction(func1)
    set.seed(42)
    a <- matrix(rnorm(1e7), 1e3)
    b <- matrix(runif(1e7), 1e3)
    
    identical(mmult(a, b), mmult1(a, b))
    #TRUE
    
    library(microbenchmark)
    microbenchmark(mmult(a, b), 
                   mmult1(a, b), 
                   cbind(a, b),
                   times = 10)
    
    #Unit: milliseconds
    #         expr    min     lq   mean median    uq   max neval
    #  mmult(a, b)  69.64  70.52  89.71  72.28 128.8 136.6    10
    # mmult1(a, b)  50.84  50.95  69.65  51.43 111.6 114.4    10
    #  cbind(a, b) 192.35 194.67 201.13 195.30 196.1 255.9    10
    

    不是什么大不了的事,但对于这样一个微不足道的改变来说也不错。

    【讨论】:

      猜你喜欢
      • 2018-01-23
      • 2018-09-03
      • 2018-02-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-25
      • 1970-01-01
      • 2020-08-19
      相关资源
      最近更新 更多