An embedded and charset-unspecified text was scrubbed... Name: not available URL: <https://stat.ethz.ch/pipermail/r-help/attachments/20101202/9d8efba9/attachment.pl>
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 :
Greetings,
My goal is to create a Markov transition matrix (probability of moving from
one state to another) with the 'highest traffic' portion of the matrix
occupying the top-left section. Consider the following sample:
inputData<- c(
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)
)
MAT<- matrix(inputData, nrow = 5, ncol = 5, byrow = TRUE)
colnames(MAT)<- c("A", "B", "C", "D", "E")
rownames(MAT)<- c("A", "B", "C", "D", "E")
rowSums(MAT)
I wan to re-arrange the elements of this matrix such that the elements with
the largest row sums are placed to the top-left, in descending order. Does
this make sense? In this case the order I'm looking for would be B, D, A, E,
C Any thoughts?
As an aside, here is the function I've written to construct the transition
matrix. Is there a more elegant way to do this that doesn't involve a double
transpose?
TMAT<- apply(t(MAT), 2, function(X) X/sum(X))
TMAT<- t(TMAT)
I tried the following:
TMAT<- apply(MAT, 1, function(X) X/sum(X))
But my the custom function is still getting applied over the columns of the
array, rather than the rows. For a check try:
rowSums(TMAT)
colSums(TMAT)
Row sums here should equal 1...
Many thanks in advance,
Aaron
[[alternative HTML version deleted]]
______________________________________________ R-help at r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code.
Ivan CALANDRA PhD Student University of Hamburg Biozentrum Grindel und Zoologisches Museum Abt. S?ugetiere Martin-Luther-King-Platz 3 D-20146 Hamburg, GERMANY +49(0)40 42838 6231 ivan.calandra at uni-hamburg.de ********** http://www.for771.uni-bonn.de http://webapp5.rrz.uni-hamburg.de/mammals/eng/1525_8_1.php
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:
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 :
Greetings,
My goal is to create a Markov transition matrix (probability of moving
from
one state to another) with the 'highest traffic' portion of the matrix
occupying the top-left section. Consider the following sample:
inputData<- c(
? ? 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)
? ? )
MAT<- matrix(inputData, nrow = 5, ncol = 5, byrow = TRUE)
colnames(MAT)<- c("A", "B", "C", "D", "E")
rownames(MAT)<- c("A", "B", "C", "D", "E")
rowSums(MAT)
I wan to re-arrange the elements of this matrix such that the elements
with
the largest row sums are placed to the top-left, in descending order. Does
this make sense? In this case the order I'm looking for would be B, D, A,
E,
C Any thoughts?
As an aside, here is the function I've written to construct the transition
matrix. Is there a more elegant way to do this that doesn't involve a
double
transpose?
TMAT<- apply(t(MAT), 2, function(X) X/sum(X))
TMAT<- t(TMAT)
I tried the following:
TMAT<- apply(MAT, 1, function(X) X/sum(X))
But my the custom function is still getting applied over the columns of
the
array, rather than the rows. For a check try:
rowSums(TMAT)
colSums(TMAT)
Row sums here should equal 1...
Many thanks in advance,
Aaron
? ? ? ?[[alternative HTML version deleted]]
______________________________________________ R-help at r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code.
-- Ivan CALANDRA PhD Student University of Hamburg Biozentrum Grindel und Zoologisches Museum Abt. S?ugetiere Martin-Luther-King-Platz 3 D-20146 Hamburg, GERMANY +49(0)40 42838 6231 ivan.calandra at uni-hamburg.de ********** http://www.for771.uni-bonn.de http://webapp5.rrz.uni-hamburg.de/mammals/eng/1525_8_1.php
______________________________________________ R-help at r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code.
An embedded and charset-unspecified text was scrubbed... Name: not available URL: <https://stat.ethz.ch/pipermail/r-help/attachments/20101202/17a179cb/attachment.pl>
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.