我有一个学生的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
我的想法是使用grades
对apply(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
?
答案 0 :(得分:1)
我们将matrix
转到data.frame
,将行名创建为一列(rownames_to_column
,mutate
除第一列外,通过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")))