B Albrecht
B Albrecht

Reputation: 3

Writing a loop/function that compares adjacent columns in a matrix and picks the max value so to reduce the number of columns

I'm new to R and stuck. I want to reduce the number of columns in a 92x8192 matrix. The matrix consists of 92 observations and each column resembles a data point in a spectrum. The value corresponds to an intensity that is an integer. I want to reduce the "resolution" (i.e. the number of data points = columns) of the spectrum in a somewhat controlled way.

Example:

     [,1] [,2] [,3] [,4] [,5] [,6] [...]
[1,]    1    2    3    4    5    6
[2,]    7    8    9   10   11   12
[3,]   13   14   15   16   17   18
[4,]   19   20   21   22   23   24
[5,]   25   26   27   28   29   30
[6,]   31   32   33   34   35   36

What i would like to do is compare adjacent columns (for each row) e.g [1,1] and [1,2], and find the max value of those two entries (that would be [1,2] in that case). The smaller value should be dropped, and the next two adjacent columns should be evaluated. So that in the end there will only be ncol/2 left. I know there is something like pmax. But since my knowledge with loops and functions is far too limited at this point i don't know how to not only compare two columns at a time but do it for all 4096 pairs of values in each row. In the end the matrix should look like this:

     [,1] [,2] [,3]  [...]
[1,]    2    4    6   
[2,]    8   10   12  
[3,]   14   16   18
[4,]   20   22   24
[5,]   26   28   30
[6,]   32   34   36

The values i have used are not a good example because i know that in this case it looks like i could just drop every other column and i know how to do that. Apologies if the question is worded in a complicated way but i think the task isn't really all that complicated.

Thanks for any help or suggestions on how to go about this task.

Upvotes: 0

Views: 158

Answers (2)

Nick
Nick

Reputation: 366

Example matrix:

> set.seed(101)
> x_full <- matrix(runif(30), nrow=5)
> x_full

           [,1]      [,2]      [,3]       [,4]      [,5]       [,6]
[1,] 0.37219838 0.3000548 0.8797957 0.59031973 0.7007115 0.79571976
[2,] 0.04382482 0.5848666 0.7068747 0.82043609 0.9568375 0.07121255
[3,] 0.70968402 0.3334671 0.7319726 0.22411848 0.2133520 0.38940777
[4,] 0.65769040 0.6220120 0.9316344 0.41166683 0.6610615 0.40645122
[5,] 0.24985572 0.5458286 0.4551206 0.03861056 0.9233189 0.65935508

Now reduce:

> x_reduced <- sapply(seq(1, ncol(x_full), 2), function(colnum) { pmax(x_full[, colnum], x_full[, colnum + 1]) })
> x_reduced

          [,1]      [,2]      [,3]
[1,] 0.3721984 0.8797957 0.7957198
[2,] 0.5848666 0.8204361 0.9568375
[3,] 0.7096840 0.7319726 0.3894078
[4,] 0.6576904 0.9316344 0.6610615
[5,] 0.5458286 0.4551206 0.9233189

How it works: seq(1, ncol(x_full), 2) generates a sequence of integers representing the odd numbers up to the number of columns of x_full. Then sapply() applies a function to this sequence and presents the results in a tidy format (in this case it happens to be a matrix as we require). The function being applied is one that we specify using function: for column numbered colnum it just applies pmax() across that column and the next.

Upvotes: 1

jimr1603
jimr1603

Reputation: 29

Example solution

    mat = mat <- matrix(1:16,nrow=4)
m <- matrix(nrow=nrow(mat),ncol=ncol(mat)/2+1) #preassign a solution matrix to save time
 for (i in seq(1,ncol(mat),2)){m[,i/2+1]<-(pmax(mat[,i],mat[,i+1]))}

your solution is then stored in m

Upvotes: 0

Related Questions