r - 如何通过column排序dataframe

在R中,我想按多列对data.frame进行排序。例如,下面的data.frame将按列z (降序)排序,然后按列b (上升)进行排序:


dd <- data.frame(b = factor(c("Hi","Med","Hi","Low"), 
 levels = c("Low","Med","Hi"), ordered = TRUE),
 x = c("A","D","A","C"), y = c(8, 3, 9, 9),
 z = c(1, 1, 1, 2))
dd
 b x y z
1 Hi A 8 1
2 Med D 3 1
3 Hi A 9 1
4 Low C 9 2

时间:

不需要用额外工具,你可以直接使用order()函数-看看这个简单的答案:


R> dd[with(dd, order(-z, b)), ]
 b x y z
4 Low C 9 2
2 Med D 3 1
1 Hi A 8 1
3 Hi A 9 1

大约2年后编辑: 它只是被问到如何用列索引做这个,答案是将所需的排序列传递到order()函数:


R> dd[ order(-dd[,4], dd[,1]), ]
 b x y z
4 Low C 9 2
2 Med D 3 1
1 Hi A 8 1
3 Hi A 9 1
R> 

德克的回答是伟大的。它同时也突显出语法用于索引的一个关键区别 data.framedata.table 年代:


## The data.frame way
dd[with(dd, order(-z, b)), ]

## The data.table way: (7 fewer characters, but that's not the important bit)
dd[order(-z, b)]

这两个调用之间的差异很小,但它可能有重要的结果。 尤其是在你编写生产代码和/或者在你的研究中关注正确性时,最好避免不必要的变量名重复。 data.table 帮助你完成这里操作。

下面是变量名称重复如何让你陷入麻烦的一个例子:

让我们改变上下文从德克回答,并说这是一个更大的项目的一部分,有很多对象名称,它们是长和有意义的,而不是 dd 叫做 quarterlyreport 。 它变成了:


quarterlyreport[with(quarterlyreport,order(-z,b)),]

好吧,好吧,没有什么问题。 下一位上司要求你在报告中包含最后一个季度报告。 你经历你的代码,添加一个对象 lastquarterlyreport 在各种地方,( 地球上如何) 你最终得到的:?


quarterlyreport[with(lastquarterlyreport,order(-z,b)),]

不是你的意思,但你没有发现它,因为你做的快,它是坐落在一个页面上类似的代码。 代码不在( 无警告和错误) 上,因为 R 认为它是你想要的。 你希望谁读你的报告,但也许他们不会。 如果你使用编程语言很多,那么这种情况可能都很熟悉。 这是个"印刷错误",你会说。 我会修复你要跟你的老板说的"印刷错误"。

data.table 中,我们关心的是像这样的微小细节。 所以我们做了一些简单的事情来避免输入变量名两次。 非常简单。idd的框架中已经被评估,自动。 你根本不需要 with()

代替


dd[with(dd, order(-z, b)), ]

它只是

 
dd[order(-z, b)]

 

而不是


quarterlyreport[with(lastquarterlyreport,order(-z,b)),]

它只是


quarterlyreport[order(-z,b)]

这是一个很小的差别,但它却能挽救你的脖子一天。 当权衡不同的回答这个问题,考虑计算变量名称的重复,在决定你的一个标准。 有些答案有很多重复,而其他的则没有。

使用Kevin Wright的这个(非常有用的)函数,R维基,这很容易实现。


> sort(dd,by = ~ -z + b)
 b x y z
4 Low C 9 2
2 Med D 3 1
1 Hi A 8 1
3 Hi A 9 1


library(dplyr)
# sort mtcars by mpg, ascending... use desc(mpg) for descending
arrange(mtcars, mpg)
# sort mtcars first by mpg, then by cyl, then by wt)
arrange(mtcars , mpg, cyl, wt)

针对操作的问题:


arrange(dd, desc(z), b)

 b x y z
1 Low C 9 2
2 Med D 3 1
3 Hi A 8 1
4 Hi A 9 1

假设你有一个data.frameA,并且希望使用称为x递减顺序的列对它进行排序。 调用排序的data.framenewdata


newdata <- A[order(-A$x),]

如果你想要升序,则将"-"替换为无。


newdata <- A[order(-A$x, A$y, -A$z),]

其中xzdata.frameA中的一些列,这意味着按x降序排序data.frameAy上升和z下降。

使用例子代码:


dd <- dd[with(dd, order(-z, b)), ] 

...