r - 如何按所有列对矩阵/数据框进行排序

标签 r sorting matrix

我有一个矩阵,例如:

a = rep(0:1, each=4)
b = rep(rep(0:1, each=2), 2)
c = rep(0:1, times=4)
mat = cbind(c,b,a)

我需要对这个矩阵的所有列进行排序。我知道如何通过对特定列(即有限数量的列)进行排序来做到这一点。
mat[order(mat[,"c"],mat[,"b"],mat[,"a"]),]
     c b a
[1,] 0 0 0
[2,] 0 0 1
[3,] 0 1 0
[4,] 0 1 1
[5,] 1 0 0
[6,] 1 0 1
[7,] 1 1 0
[8,] 1 1 1

但是,我需要一种不调用任何列名的通用方法,因为我可以有任意数量的列。如何按大量列排序?

最佳答案

这是一个简洁的解决方案:

mat[do.call(order,as.data.frame(mat)),];
##      c b a
## [1,] 0 0 0
## [2,] 0 0 1
## [3,] 0 1 0
## [4,] 0 1 1
## [5,] 1 0 0
## [6,] 1 0 1
## [7,] 1 1 0
## [8,] 1 1 1

调用 as.data.frame()以直观的方式将矩阵转换为 data.frame,即每个矩阵列成为新 data.frame 中的列表组件。由此,您可以有效地将每个矩阵列传递给 order() 的单个调用。通过将矩阵的列表形式作为 do.call() 的第二个参数传递.

这适用于任意数量的列。

这不是一个愚蠢的问题。原因mat[order(as.data.frame(mat)),]不工作是因为 order()不按行对 data.frames 进行排序。

它不是基于从左到右对列向量进行排序(这是我的解决方案所做的)返回 data.frame 的行顺序,而是基本上将 data.frame 展平为单个大向量并对其进行排序。

所以,实际上,order(as.data.frame(mat))相当于 order(mat) ,因为矩阵也被视为平面向量。

对于您的特定数据,这将返回 24 个索引,理论上可以用于索引(作为向量)原始矩阵 mat ,但由于在表达式 mat[order(as.data.frame(mat)),] 中您正在尝试使用它们来索引 mat 的行维度,某些索引超过了最高行索引,因此您会收到“下标越界”错误。

?do.call .

我不认为我可以比帮助页面更好地解释它;看一看这些例子,和他们一起玩,直到你明白它是如何工作的。基本上,当您想传递给单个函数调用的参数被困在列表中时,您需要调用它。

你不能传递列表本身(因为你没有传递预期的参数,你传递的是一个包含预期参数的列表),所以必须有一个原始函数从列表中“解开”参数函数调用。

这是编程语言中的常见原语,其中函数是一等对象,特别是(除了 R 的 do.call() )JavaScript 的 apply() ,Python 的(已弃用) apply() , 和 vim 的 call() .

关于r - 如何按所有列对矩阵/数据框进行排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29482983/

相关文章:

r - 在 dplyr 中按组获取总和后计算列的行百分比

r - 在 r 中使用 ggplot 添加点到 usmap

MySQL 排序 DESC 和 ASC

javascript - array.sort() 没有给出所需的结果

javascript - 使用 ctx.getTransformation() 获取变换后的 Canvas 鼠标坐标

使用 lm() 和 predict() 进行滚动回归和预测

r - 使用 stargazer 进行生活并出现错误

tsql - 在 SQL 中对 IP 地址进行排序

python - 创建一个带有元素的 numpy 矩阵作为索引的函数

r - 创建一个整数相似矩阵,使用 R