簡體   English   中英

如何按所有列對矩陣/數據框進行排序

[英]How to sort a matrix/data.frame by all columns

我有一個矩陣,例如:

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 中的列表組件。 由此,您可以通過將矩陣的列表形式作為do.call()的第二個參數傳遞來有效地將每個矩陣列傳遞給order()的單個調用。

這適用於任意數量的列。


這不是一個愚蠢的問題。 之所以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()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM