Reputation: 794
So I am sorting a matrix one row at a time in descending that is 130X130, and I want to create a new matrix where the row name is the same, but the each sorted row column names are where the data was and the data in parenthesis next to the according column name. Its kind of like creating a psuedo3D array of the dimension 130x130x2 and then condensing it into a 130x130 matrix without column names. Here's a smaller example.
Example
A B C D
A 14 82 18 50
B 39 95 27 19
C 60 40 32 15
D 70 31 69 31
This is what I want
A B(82) D(50) C(18) A(14)
B B(95) A(39) C(27) D(19)
C A(60) B(40) C(32) D(15)
D A(70) C(69) B(31) D(31)
I hope this makes sense!
Thanks!
Upvotes: 1
Views: 148
Reputation: 179388
Here you go:
First, recreate your data:
x <- read.table(text="
A B C D
A 14 82 18 50
B 39 95 27 19
C 60 40 32 15
D 70 31 69 31", header=TRUE)
Two apply()
s, a paste()
and a matrix()
, and the rest is details:
o <- apply(x, 1, order, decreasing=TRUE)
v <- apply(x, 1, sort, decreasing=TRUE)
matrix(paste(names(x)[o], t(v)), ncol=4, byrow=TRUE)
[,1] [,2] [,3] [,4]
[1,] "B 82" "D 50" "C 18" "A 14"
[2,] "B 95" "A 39" "C 27" "D 19"
[3,] "A 60" "B 40" "C 32" "D 15"
[4,] "A 70" "C 69" "B 31" "D 31"
EDIT: Based on a comment by Jeff Allen, this can be further simplified to:
t(apply(x, 1, function(x){s <- order(x, decreasing=TRUE); paste(names(x)[s], x[s])}))
[,1] [,2] [,3] [,4]
A "B 82" "D 50" "C 18" "A 14"
B "B 95" "A 39" "C 27" "D 19"
C "A 60" "B 40" "C 32" "D 15"
D "A 70" "C 69" "B 31" "D 31"
(Since this has only one apply
it should be even faster.)
Upvotes: 6
Reputation: 17517
I'm hoping someone will propose a vectorized solution, but here's one option:
sortTab <- function(tab){
for (i in 1:nrow(tab)){
#Get the order of the elements in the current row
ord <- order(tab[i,], decreasing=TRUE)
#get the associated column names and values with this ordering
res <- paste(colnames(tab)[ord], "(", tab[i,ord], ")", sep="")
#assign back to the data.frame
tab[i,] <- res
}
tab
}
And a test using your data:
txt <- textConnection(" A B C D
A 14 82 18 50
B 39 95 27 19
C 60 40 32 15
D 70 31 69 31")
tab <- read.table(txt)
> sortTab(tab)
A B C D
A B(82) D(50) C(18) A(14)
B B(95) A(39) C(27) D(19)
C A(60) B(40) C(32) D(15)
D A(70) C(69) B(31) D(31)
Upvotes: 3