在 R 中对矩阵元素进行排序和计数
Ranking and Counting Matrix Elements in R
我知道有类似的问题,但我找不到问题的答案。我正在尝试对矩阵中的元素进行排序,然后提取 5 个最高元素的数据。
这是我的尝试。
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")
但这并没有帮助,因为它只是以矢量格式吐出排名。
我最终想要的是一个包含的数据框(或任何类型的 table)
矩阵中最高 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
感谢您的回答。那些完全符合我的目的,但由于我是 运行 相关图表的代码 - 每对都会有重复的数字 - 我只想计算两个数字中的一个用于排名目的。有什么办法吗?谢谢
这是一个非常粗略的方法:
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) <-
更改它们。
这里有一个选项 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)
这是基本 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
结果可以(轻松)变得更清晰(参见 Frank 的评论):
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
我知道有类似的问题,但我找不到问题的答案。我正在尝试对矩阵中的元素进行排序,然后提取 5 个最高元素的数据。
这是我的尝试。
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")
但这并没有帮助,因为它只是以矢量格式吐出排名。 我最终想要的是一个包含的数据框(或任何类型的 table) 矩阵中最高 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
感谢您的回答。那些完全符合我的目的,但由于我是 运行 相关图表的代码 - 每对都会有重复的数字 - 我只想计算两个数字中的一个用于排名目的。有什么办法吗?谢谢
这是一个非常粗略的方法:
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) <-
更改它们。
这里有一个选项 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)
这是基本 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
结果可以(轻松)变得更清晰(参见 Frank 的评论):
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