Search code examples
rmatrixsmoothing

How to combine data from different columns, e.g. mean of surrounding columns for a given column


I am trying to smooth a matrix by attributing the mean value of a window covering n columns around a given column. I've managed to do it but I'd like to see how would be 'the R way' of doing it as I am making use of for loops. Is there a way to get this using apply or some function of the same family?

Example:

# create a toy matrix
mat <- matrix(ncol=200);
for(i in 1:100){ mat <- rbind(mat,sample(1:200, 200) )}
# quick visualization
image(t(mat))

enter image description here

This is the matrix before smoothing:

I wrote the function smooth_mat that takes a matrix and the length of the smoothing kernel:

smooth_row_mat <- function(k, k.d=5){
    k.range <- (k.d + 2):(ncol(k) - k.d - 1)
    k.smooth <- matrix(nrow=nrow(k))
    for( i in k.range){
            if (i  %% 10 == 0)      cat('\r',round(i/length(k.range), 2))
            k.smooth <- cbind( k.smooth, rowMeans(k[,c(  (i-1-k.d):(i-1) ,i, (i+1):(i + 1 - k.d) )]) )
    }
    return(k.smooth)

}

Now we use smooth_row_mat() with mat

mat.smooth <- smooth_mat(mat)

And we have successfully smoothed, on a row basis, the content of the matrix.

This is the matrix after: enter image description here

This method is good for such a small matrix although my real matrices are around 40,000 x 400, still works but I'd like to improve my R skills.

Thanks!


Solution

  • You can apply a filter (running mean) across each row of your matrix as follows:

    apply(k, 1, filter, rep(1/k.d, k.d))