[S] Summary: subtracting a constant from each col of a matrix

Joe Davis (jdavis@spdc.ti.com)
Thu, 19 Mar 1998 07:32:35 -0600

I have recieved many responses and it appears that there are quite a number of
different ways to
improve upon my original method.

My thanks go out to everyone who replied.


The original components:

a <- c(1,2,3)
X <- cbind(c(1,1,1),c(2,2,2),c(3,3,3))

My original method of getting b - X:

b <- matrix(a,nrow=ncol(X),ncol=length(a), byrow=T)
d1 <- b - X
Better Solutions:

#1) use the sweep function
(thanks to Patric Burns, Rainer Kegel, Angelo J. Canty, Carl Boe,Phil
Christian Keller, Nader Tajvidi, and Gareth Staton)

d1 <- sweep(X,2,a) or sweep(X,2,a,"-")

#2) use "-" operator in the apply function
(thanks to Claus Dethlefsen, Nicole Demers)

d1 <- apply(X,1,"-", a)

#3) transpose the X matrix to get the rows/cols correct before using the unary
(thanks to L. Molinari, Douglas Bates , A Dorfman, Rolf Turner, Coen
Bernaards, Dave

d1 <- t(t(X)-a)

Rolf Turner provides an explanation:

> O. K. Why does this work? Because
> (a) S stores matrices column by column
> (b) When S subtracts 1 vector from another
> it ``recyles'' the shorter one as many times
> (possibly a fractional number of times) as
> needed.
> Try (1:3) - (1:7) to see what happens.

#4) Use the 'scale' function
(thanks to Tim Hesterberg)

d1 <- scale(X, center=a, scale=FALSE)

#5) Use the matrix library
(thanks to Nick Ellis)

#6) create your own binary function "%-%"
(thanks to Bill Venables)

%-%" <- function(X, a) {
if(!is.matrix(X)) stop("X is not a matrix!")
if(length(a) != ncol(X))
a <- rep(a, length = ncol(X))
X - rep(a, rep(nrow(X), ncol(X))

You can add a few more sanity checks, of course. Now you can use
it as a binary operator

d1 <- X %-% a

     Joseph C. Davis               Texas Instruments, Inc
  Process Flow Synthesis          P.O. Box 655012, MS 3704
     (972) 927-3805                   Dallas, TX 75265
This message was distributed by s-news@wubios.wustl.edu.  To unsubscribe
send e-mail to s-news-request@wubios.wustl.edu with the BODY of the
message:  unsubscribe s-news