Skip to content

Arrange elements on a matrix according to rowSums + short 'apply' Q

5 messages · Aaron Polhamus, Ivan Calandra, Michael Bedward +1 more

#
Hi,

Here is a not so easy way to do your first step, but it works:
MAT2 <- cbind(MAT, rowSums(MAT))
MAT[order(MAT2[,6], decreasing=TRUE),]

For the second, I don't know!

HTH,
Ivan


Le 12/2/2010 09:46, Aaron Polhamus a ?crit :

  
    
#
Hi Aaron,

Following up on Ivan's suggestion, if you want the column order to
mirror the row order...

mo <- order(rowSums(MAT), decreasing=TRUE)
MAT2 <- MAT[mo, mo]

Also, you don't need all those extra c() calls when creating
inputData, just the outermost one.

Regarding your second question, your statements...

TMAT <- apply(t(MAT), 2, function(X) X/sum(X))
TMAT <- t(TMAT)

is actually just a complicated way of doing this...

TMAT <- MAT / rowSums(MAT)

You can confirm that by doing it your way and then this...

TMAT == MAT / rowSums(MAT)

...and you should see a matrix of TRUE values

Michael
On 2 December 2010 20:43, Ivan Calandra <ivan.calandra at uni-hamburg.de> wrote:
#
On Thu, Dec 02, 2010 at 01:13:40PM -0800, Aaron Polhamus wrote:
...
In the command

TMAT <- apply(MAT, 1, function(X) X/sum(X))

the custom function is applied over rows of MAT, however, when
collecting the obtained (originally) rows to a matrix, they
become columns, due to the following rule from ?apply

     If each call to ?FUN? returns a vector of length ?n?, then ?apply?
     returns an array of dimension ?c(n, dim(X)[MARGIN])? if ?n > 1?.

Here, n is the length of the original rows and dim(X)[MARGIN] is
the number of rows of the input matrix. So, the order of the 
dimensions gets reversed in this case.

The following demonstrates that apply(t(MAT), 2, ) and apply(MAT, 1, )
produce the same matrix except of a transposition.

  MAT <- rbind(
      c(5, 3, 1, 6, 7),
      c(9, 7, 3, 10, 11),
      c(1, 2, 3, 4, 5),
      c(2, 4, 6, 8, 10),
      c(9, 5, 2, 1, 1)
      )
  colnames(MAT) <- c("A", "B", "C", "D", "E")
  rownames(MAT) <- c("A", "B", "C", "D", "E")
  
  A <- apply(t(MAT), 2, function(X) X/sum(X))
  A <- t(A)
  
  B <- apply(MAT, 1, function(X) X/sum(X))
  
  all(A == t(B)) # [1] TRUE

The "dual" command to M / rowSums(M), which divides each element
of a matrix M by the sum of its column, may be done, for example

  M <- matrix(1:12, nrow=3)
  M1 <- M / rep(colSums(M), each=dim(M)[1])
            [,1]      [,2]      [,3]      [,4]
  [1,] 0.1666667 0.2666667 0.2916667 0.3030303
  [2,] 0.3333333 0.3333333 0.3333333 0.3333333
  [3,] 0.5000000 0.4000000 0.3750000 0.3636364

  M/M1
       [,1] [,2] [,3] [,4]
  [1,]    6   15   24   33
  [2,]    6   15   24   33
  [3,]    6   15   24   33

Alternatively, it is possible to use

  sweep(M, 2, colSums(M), FUN="/")

Petr Savicky.