如何按所有列对矩阵进行排序

时间:2012-05-09 00:29:54

标签: r sorting

假设我有

arr = 2 1 3
      1 2 3
      1 1 2

我如何将其排序到下面?

arr = 1 1 2
      1 2 3
      2 1 3

即,首先是第一列,然后是第二列等。

4 个答案:

答案 0 :(得分:20)

你所追求的功能是order(我是如何得出这个结论的 - 我的第一个想法是“好,排序,sort怎么样?”。试过sort(arr)看起来它将arr排序为向量而不是按行排序。查看?sort,我会在“另请参阅:order中看到排序或重新排序多个变量。“)。

查看?order,我看到order(x,y,z, ...)将按x排序,按y打破关联,通过z打破更多联系,依此类推。太棒了 - 我所要做的就是将arr的每一栏传递到order来执行此操作。 (在?order)的示例部分中甚至有一个例子:

order( arr[,1], arr[,2], arr[,3] ) 
# gives 3 2 1: row 3 first, then row 2, then row 1.
# Hence:
arr[ order( arr[,1], arr[,2], arr[,3] ), ]
#     [,1] [,2] [,3]
#[1,]    1    1    2
#[2,]    1    2    3
#[3,]    2    1    3

大!


但是,我必须在arr[,i]中为每个列写出arr,这有点令人讨厌 - 如果我不知道它有多少列,该怎么办?推进?

嗯,这些示例显示了如何执行此操作:使用do.call。基本上,你这样做:

do.call( order, args )

其中argsorder参数的列表。因此,如果您可以在arr的每列中列出一个列表,那么您可以将其用作args

执行此操作的一种方法是将arr转换为数据框,然后转换为列表 - 这将自动为列表的每个元素放置一列:

arr[ do.call( order, as.list(as.data.frame(arr)) ), ]

as.list(as.data.frame有点麻烦 - 当然还有其他方法来创建列表,list[[i]]i的{​​{1}}列,但这只是之一。

答案 1 :(得分:16)

这样可行:

arr[do.call(order, lapply(1:NCOL(arr), function(i) arr[, i])), ]

它正在做的是:

arr[order(arr[, 1], arr[, 2], arr[ , 3]), ]

除了它允许矩阵中的任意数量的列。

答案 2 :(得分:1)

我写了这个小func,也做了降序 cols允许选择要订购的列及其订单

ord.mat = function(M, decr = F, cols = NULL){
    if(is.null(cols))
      cols = 1: ncol(M)
    out = do.call( "order", as.data.frame(M[,cols]))
    if (decr)
      out = rev(out)
    return(M[out,])
}

答案 3 :(得分:1)

我有类似的问题,解决方案似乎简单而优雅:

t(apply(t(yourMatrix),2,sort))