使用 Rcpp 的 R 快速 cbind 矩阵 [英] R fast cbind matrix using Rcpp

查看:49
本文介绍了使用 Rcpp 的 R 快速 cbind 矩阵的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

cbind in R is relatively time consuming in repeated calls, but it also is powerful for various data types. I have written code that is 3X faster than cbind when binding two matrices. But bind_cols in dplyr package is merely 100X faster than cbind. It is only a pity that it cannot take matrix as input. Can someone make the code below more fast. Also, how do I fast bind sparse matrix? Here is the code I used:

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))

推荐答案

借鉴这个想法 评论 Romain Francois 对我以前的 Rcpp 冒险之一的评论,

Borrowing an idea from this comment by Romain Francois on one of my previous Rcpp adventures,

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

没什么大不了的,但对于这样一个微不足道的变化来说也不错.

Not a huge deal, but not bad either for such a trivial change.

这篇关于使用 Rcpp 的 R 快速 cbind 矩阵的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆