[R] Column wise matrix multiplication

Petr Savicky savicky at cs.cas.cz
Tue Feb 21 07:51:33 CET 2012


On Mon, Feb 20, 2012 at 09:33:28PM -0000, Ted Harding wrote:
[...]
> > Unfortunately, there seems to be no equivalent for products
> > (e.g. "rowProds"). But you can define one:
> > 
> >   rowProds <- function(X){ apply(X,1,FUN="prod") }
> > 
> >   rowProds(A)
> >   # [1]  6 14 24 36 50
> > 
> > Even then, the result is a "simple R vector", without dimensions:
> > 
> >   dim(rowProds(A))
> >   # NULL
> > 
> > If you need an array (row) vector then you can apply t():
> > 
> >   t(rowProds(A))
> >   #      [,1] [,2] [,3] [,4] [,5]
> >   # [1,]    6   14   24   36   50
> > 
> > or t(t()) for a column vector:
> > 
> >   t(t(rowProds(A)))
> >   #      [,1]
> >   # [1,]    6
> >   # [2,]   14
> >   # [3,]   24
> >   # [4,]   36
> >   # [5,]   50
> > 
> > Ted.
> > 
> > -------------------------------------------------
> 
> Further to the above: I have managed to track down a
> function rowProds in the "matrixStats" package:
> 
> http://finzi.psych.upenn.edu/R/library/matrixStats/html/rowProds.html
> 
> http://www.stats.bris.ac.uk/R/web/packages/matrixStats/matrixStats.pdf
> 
> Note that:
> 
>   "Details
>    Internally the product is calculated via the logarithmic
>    transform, treating zeros and negative values specially."
> 
> In view of this, which strikes me as potentially getting
> close to thin ice, plus the overhead of loading a whole
> package just for one function, it may be more straightforward
> (and perhaps safer) to define one's own function (as above).
> Also (see the PDF reference manual) it is apparently "work
> in progress" and also has dependencies on other packages:
> see the description at
> 
> http://www.stats.bris.ac.uk/R/web/packages/matrixStats/index.html

Hi.

Computing the componentwise product of the columns may be
done also as follows.

  rowProds2 <- function(a) Reduce("*", as.data.frame(a))

For a matrix with a large number of rows, this is more
efficient, since it contains a cycle over columns and
not a cycle over rows as apply(a, 1, prod).

  rowProds <- function(X){ apply(X,1,FUN="prod") }

  m <- 100000
  a <- matrix(sample(0 + 1:10, 10*m, replace=TRUE), nrow=m, ncol=10)
  t1 <- system.time( out1 <- rowProds(a))
  t2 <- system.time( out2 <- rowProds2(a))
  identical(out1, out2)

  [1] TRUE

  rbind(t1, t2)

     user.self sys.self elapsed user.child sys.child
  t1     0.550    0.003   0.553          0         0
  t2     0.049    0.013   0.062          0         0

Petr Savicky.



More information about the R-help mailing list