2016-07-29 61 views
1

我知道有类似的问题,但我找不到我的问题的答案。我试图排列矩阵中的元素,然后提取5个最高元素的数据。R中排名和计数矩阵元素

这是我的尝试。

set.seed(20) 
d<-matrix(rnorm(100),nrow=10,ncol=10) 
start<-d[1,1] 
for (i in 1:10) { 
for (j in 1:10) { 
    if (start < d[i,j]) 
    {high<-d[i,j] 
    rowind<-i 
    colind<-j 
    } 
    } 
} 

虽然这给了我最高的元素的数据,包括行数和列数,我不能想办法做同样从2排至5元我也试过

rank(d, ties.method="max") 

但它没有帮助,因为它只是吐出了矢量格式的排名。 我最终想要的是一个数据框(或任何类型的表),其中包含 排名,列名,行名,以及矩阵中最高5个元素的数据(数字)。

编辑

set.seed(20) 
d<-matrix(rnorm(100),nrow=10,ncol=10) 
d[1,2]<-5 
d[2,1]<-5 
d[1,3]<-4 
d[3,1]<-4 

感谢您的答案。那些完美的工作是为了我的目的,但是因为我正在为关联图表运行此代码 - 其中每个对都会有重复的数字 - 我只想为排名目的计算两个数字中的一个。有没有办法做到这一点?谢谢。

+0

它是按行还是列? – akrun

+0

请在制作随机示例之前使用set.seed。使人们更容易验证和比较答案。 – Frank

+0

@Frank感谢您的建议。只是做了改变。 – sh2657

回答

3

这里是一个非常粗暴的方式:

DF = data.frame(row = c(row(d)), col = c(col(d)), v = c(d)) 
DF[order(DF$v, decreasing=TRUE), ][1:5, ] 

    row col  v 
91 1 10 2.208443 
82 2 9 1.921899 
3 3 1 1.785465 
32 2 4 1.590146 
33 3 4 1.556143 

这将是很好,只需要一部分的排序,但在?order,它看起来像此选项仅适用于sort,不为order


如果矩阵有行名和列名,可能很方便看到它们而不是数字。下面是我可以做什么:

dimnames(d) <- list(letters[1:10], letters[1:10]) 
DF = data.frame(as.table(d)) 

DF[order(DF$Freq, decreasing=TRUE), ][1:5, ] 

    Var1 Var2  Freq 
91 a j 2.208443 
82 b i 1.921899 
3  c a 1.785465 
32 b d 1.590146 
33 c d 1.556143 

列名在此不作太大的意义,很不幸,但你可以names(DF) <-照常进行更改。

+0

谢谢你的答案弗兰克。有什么办法可以调用行和列名而不是数字吗?如果我有姓名(d)< - c(“a”,“b”,“c”,“d”,“e”,“f”,“g”,“h”,“i”,“j” )和rownames(d)< - c(“a”,“b”,“c”,“d”,“e”,“f”,“g”,“h”,“i”,“j”) – sh2657

+0

@ sh2657我已经添加了一种解决方法。这应该也适用,如果你有一个超过两个维数组'a = array(1:8,c(2,2,2)); data.frame(as.table的(a))'。如果空白,则每个昏暗的名称会自动填入。 – Frank

+0

完美适用于此目的。非常感谢。 – sh2657

2

这里是一个选项与Matrix

library(Matrix) 
m1 <- summary(Matrix(d, sparse=TRUE)) 
head(m1[order(-m1[,3]),],5) 
# i j  x 
#93 3 10 2.359634 
#31 1 4 2.234804 
#23 3 3 1.980956 
#55 5 6 1.801341 
#16 6 2 1.678989 

或者使用melt

library(reshape2) 
m2 <- melt(d) 
head(m2[order(-m2[,3]), ], 5) 
+0

没有理由将OP的示例矩阵存储为稀疏的,我猜。 – Frank

+0

@Frank这是得到'摘要' – akrun

+0

好吧,我明白了。之前没有使用过这个函数,并且认为它与存储稀疏有关,不要猜测。 – Frank

1

这里是东西基地R.

# set.seed(20) 
# d <- matrix(rnorm(100), nrow = 10, ncol = 10) 

d.rank <- matrix(rank(-d), nrow = 10, ncol = 10) 

which(d.rank <= 5, arr.ind=TRUE) 
    row col 
[1,] 3 1 
[2,] 2 4 
[3,] 3 4 
[4,] 2 9 
[5,] 1 10 

d[d.rank <= 5] 
[1] 1.785465 1.590146 1.556143 1.921899 2.208443 

结果很简单(很容易)变得更清晰(参见弗兰克的评论):

cbind(which(d.rank <= 5, arr.ind=TRUE), v = d[d.rank <= 5], rank = rank(-d[d.rank <= 5])) 

    row col  v rank 
[1,] 3 1 1.785465 3 
[2,] 2 4 1.590146 4 
[3,] 3 4 1.556143 5 
[4,] 2 9 1.921899 2 
[5,] 1 10 2.208443 1 
+1

可以交替'cbind(其中(d.rank <= 5,arr.ind = TRUE),v = d [d .rank <= 5])'以便更清楚地表明您的结果是正确的/匹配其他答案。 (不知道我的'cbind'实际上是否正确,但是。) – Frank