Get rank of matrix entries?
Assume a matrix:
> a <- matrix(c(100, 90, 80, 20), 2, 2)
> a
[,1] [,2]
[1,] 100 80
开发者_如何学JAVA[2,] 90 20
Suppose I want to convert the elements of the matrix to ranks:
>rank.a <- rank(a)
> rank.a
[1] 4 3 2 1
This returns a vector, i.e. the matrix structure is lost. Is it possible to rank a matrix such that the output will be of the form:
[,1] [,2]
[1,] 4 2
[2,] 3 1
An alternative to @EDi's Answer is to copy a
and then assign the output of rank(a)
directly into the elements of the copy of a
:
> a <- matrix(c(100, 90, 80, 20), 2, 2)
> rank.a <- a
> rank.a[] <- rank(a)
> rank.a
[,1] [,2]
[1,] 4 2
[2,] 3 1
That saves you from rebuilding a matrix by interrogating the dimensions of the input matrix.
Note that (as @Andrie mentions in the comments) the copying of a
is only required if one wants to keep the original a
. The main point to note is that because a
is already of the appropriate dimensions, we can treat it like a vector and replace the contents of a
with the vector of ranks of a
.
why not convert the vector back to a matrix, with the dimensions of the original matrix?
> a <- matrix(c(100, 90, 80, 20, 10, 5), 2, 3)
> a
[,1] [,2] [,3]
[1,] 100 80 10
[2,] 90 20 5
> rank(a)
[1] 6 5 4 3 2 1
> rmat <- matrix(rank(a), nrow = dim(a)[1], ncol = dim(a)[2])
> rmat
[,1] [,2] [,3]
[1,] 6 4 2
[2,] 5 3 1
@Gavin Simpson has a very nice and elegant solution! But there is one caveat though:
The type of the matrix will stay the same or be widened. Mostly you wouldn't notice, but consider the following:
a <- matrix( sample(letters, 4), 2, 2)
rank.a <- a
rank.a[] <- rank(a)
typeof(rank.a) # character
Since the matrix was character to start with, the rank
values (which are doubles) got coerced into character strings!
Here's a safer way that simply copies all the attributes:
a <- matrix( sample(letters, 4), 2, 2)
rank.a <- rank(a)
attributes(rank.a) <- attributes(a)
typeof(rank.a) # double
Or, as a one-liner using structure
to copy only the relevant attributes (but more typing):
a <- matrix( sample(letters, 4), 2, 2)
rank.a <- structure(rank(a), dim=dim(a), dimnames=dimnames(a))
Of course, dimnames
could be left out in this particular case.
精彩评论