Arrange elements on a matrix according to rowSums + short 'apply' Q
On Thu, Dec 02, 2010 at 01:13:40PM -0800, Aaron Polhamus wrote:
...
Many thanks for the tips, those solved my queries. Still interested in how to force custom functions to work over rows rather than columns when using apply,
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.