如何根据排序的数字矩阵对字符矩阵进行排序?

时间:2019-04-20 16:45:37

标签: r

我有一个学生的grades矩阵。

         Winston  Ariana  James
Math          50      70     90
Science       85      90     50
Biology       40      30     80

如何将该矩阵转换为学生表现最好的课程的排序矩阵?

Winston   Ariana   James
Science   Science  Math 
Math      Math     Biology
Biology   Biology  Science

我的想法是使用gradesapply(grades, 2, sort, decreasing=TRUE)矩阵进行排序,然后像这样创建一个矩阵(我们称其为temp):matrix(rownames(grades), nrow=nrow(grades), ncol=ncol(grades), dimnames=list(c(NULL), c(colnames(grades)))),其中每一行临时矩阵将由成绩的行名填充。然后以某种方式将grades的值传递给temp,然后对它进行排序。

谁能以更好的方式帮助解决此问题,或者让我知道如何在不更改grades元素的情况下将temp的值传递给temp

1 个答案:

答案 0 :(得分:1)

我们将matrix转到data.frame,将行名创建为一列(rownames_to_columnmutate除第一列外,通过order值以降序排列,然后使用该值索引以重新排列每列中的行名,将“ rn”列转换回行名,然后再次将其更改为matrix

library(tidyverse)
m1 %>% 
  as.data.frame %>% 
  rownames_to_column('rn') %>%
  mutate_at(-1, list(~ rn[order(., decreasing = TRUE)])) %>%
  column_to_rownames('rn') %>%
  as.matrix
#     Winston   Ariana    James    
#Math    "Science" "Science" "Math"   
#Science "Math"    "Math"    "Biology"
#Biology "Biology" "Biology" "Science"

或者我们可以将melt转换为'long'格式,以'long'格式进行arrange,然后进行spread

library(reshape2)
melt(m1) %>%
   arrange(Var2, desc(value)) %>% 
   group_by(Var2) %>%      
   mutate(rn = row_number()) %>%
   dplyr::select(-value) %>% 
   spread(Var2, Var1)

或者使用base R,循环浏览matrix的列,order以递减的顺序排列列值,使用索引按上述顺序对行名进行排序

apply(m1, 2, function(x) row.names(m1)[order(x, decreasing = TRUE)])
#    Winston   Ariana    James    
#[1,] "Science" "Science" "Math"   
#[2,] "Math"    "Math"    "Biology"
#[3,] "Biology" "Biology" "Science"

数据

m1 <- structure(c(50L, 85L, 40L, 70L, 90L, 30L, 90L, 50L, 80L), .Dim = c(3L, 
 3L), .Dimnames = list(c("Math", "Science", "Biology"),
  c("Winston", "Ariana", "James")))