2015-08-10 14 views
6

cbind R'yi kullanarak tekrarlanan çağrılarda nispeten zaman alır, ancak çeşitli veri türleri için de güçlüdür. İki matris bağlanırken, cbind'dan 3X daha hızlı yazılmış bir kod yazdım. Ancak dplyr paketindeki bind_cols, cbind'dan yalnızca 100X daha hızlıdır. Matrisin girdi olarak alınamaması sadece üzücüdür. Birisi kodu daha hızlı yapabilir. Ayrıca, seyrek matrisi hızlı bir şekilde nasıl bağlarım? Böyle bir için de fenaR hızlı cbind matrisi, Rcpp

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

cevap

4

önceki Rcpp maceralarından birinde Romain Francois tarafından bu comment gelen bir fikir ödünç alarak,

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 

Büyük bir anlaşma değil, ancak: İşte kullanılan koddur önemsiz değişim.