开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜