title: Efficiently center a large matrix in R
body: <p>I have a large matrix that I would like to center:</p>
  
  <pre><code>X &lt;- matrix(sample(1:10, 5e+08, replace=TRUE), ncol=10000)
  </code></pre>
  
  <p>Finding the the means is quick and efficient with colMeans:</p>
  
  <pre><code>means &lt;- colMeans(X)
  </code></pre>
  
  <p>But what's a good (fast and memory efficient) way to subtract the respective mean from each column?  This works, but it doesn't feel right:</p>
  
  <pre><code>for (i in 1:length(means)){
    X[,i] &lt;- X[,i]-means[i] 
  }
  </code></pre>
  
  <p>Is there a better way?</p>
  
  <p>/edit: Here's a modification the the various benchmarks DWin wrote, on a larger matrix, including the other posted suggestions:</p>
  
  <pre><code>require(rbenchmark)
  X &lt;- matrix(sample(1:10, 5e+07, replace=TRUE), ncol=10000)
  frlp.c &lt;- compiler:::cmpfun(function(mat){
    means &lt;- colMeans(mat)
    for (i in 1:length(means)){
      mat[,i] &lt;- mat[,i]-means[i] 
    }
    return(mat)
  })
  
  mat.c &lt;- compiler:::cmpfun(function(mat){
    t(t(X) - colMeans(X))
  })
  
  swp.c &lt;- compiler:::cmpfun(function(mat){
    sweep(mat, 2, colMeans(mat), FUN='-')
  })
  
  scl.c &lt;- compiler:::cmpfun(function(mat){
    scale(mat, scale=FALSE)
  })
  
  matmult.c &lt;- compiler:::cmpfun(function(mat){
    mat-rep(1, nrow(mat)) %*% t(colMeans(mat))
  })
  
  benchmark( 
    frlp.c=frlp.c(X),
    mat=mat.c(X),
    swp=swp.c(X),
    scl=scl.c(X), 
    matmult=matmult.c(X),
    replications=10,
    order=c('replications', 'elapsed'))
  </code></pre>
  
  <p>The matmult function seems to be new winner!  I really want to try these out on a 5e+08 element matrix, but I keep running out of RAM.</p>
  
  <pre><code>     test replications elapsed relative user.self sys.self user.child sys.child
  5 matmult           10   11.98    1.000      7.47     4.47         NA        NA
  1  frlp.c           10   35.05    2.926     31.66     3.32         NA        NA
  2     mat           10   50.56    4.220     44.52     5.67         NA        NA
  4     scl           10   58.86    4.913     50.26     8.42         NA        NA
  3     swp           10   61.25    5.113     51.98     8.64         NA        NA
  </code></pre>