2016-07-29 6 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

Спасибо за ответ Фрэнк. Есть ли способ, которым я могу вызывать имена строк и столбцов вместо чисел? Если у меня есть colnames (d) <- c ("a", "b", "c", "d", "e", "f", "g", "h", "i", "j") и имена ростов (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 (а)) '. Имена вдоль каждого тускнеют автоматически, если пустые. – 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 Он должен получить 'summary' – 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

Смежные вопросы