跳至主要内容

如何在 R 中排序数据:完整教程

学习如何使用 order()、sort() 和 dplyr 的 arrange() 在 R 中对向量、数据框等进行排序,并配以实用示例。
· 6分钟 阅读

使用 AI 探索

R 提供多种方式按升序或降序对数据进行排序;数据分析师和数据科学家会根据数据结构使用 order()、sort() 以及如 dplyr 等包来完成排序。

要点速览

  • 使用 sort() 直接对向量排序并返回排好序的值
  • 使用 order() 获取可将向量排好序的索引——非常适合用于数据框排序
  • 使用 dplyr::arrange() 以现代、易读的方式排序数据框
  • 通过 na.last 参数处理 NA 值(TRUE 将 NA 放在末尾,FALSE 放在开头)
  • 使用 decreasing = TRUE 或负号实现降序排序

order() 可用于对向量、矩阵排序,也能借助它对 数据框 进行升序或降序排序,详见本教程最后一节。

order() 的语法

sort() 函数

在深入了解 order() 之前,先看看更简单的 sort() 函数。与返回索引的 order() 不同,sort() 会直接返回排好序的值:

# Create a vector
values <- c(4, 12, 6, 7, 2, 9, 5)

# sort() returns the sorted values directly
sort(values)
[1]  2  4  5  6  7  9 12

关键区别在于,sort() 给出的是排好序的实际值,而 order() 给出的是位置索引。这使得 order() 在排序数据框时更为实用,后文将进一步说明。

order() 的语法

order() 的语法如下:

order(x, decreasing = TRUE or FALSE, na.last = TRUE or FALSE, method = c("auto", "shell", "quick", "radix"))

上述 order() 参数含义如下:

  • x: 数据框、矩阵或向量
  • decreasing: 布尔值;TRUE 表示降序,FALSE 表示升序。
  • na.last: 布尔值;TRUE 表示将 NA 索引置于末尾,FALSE 表示置于开头。
  • method: 使用的排序方法。

R 中的 order()

下面看一个 order() 的实际例子。

以下代码创建了一个包含一组数字的向量 y。我将使用 order(y) 获取可将这些数字排好序的索引。

y <- c(4, 12, 6, 7, 2, 9, 5)
order(y)

上述代码的输出如下:

5 1 7 3 4 6 2

此处 order() 会按索引返回使给定数字升序排列的顺序。由于数字 2 最小,其索引为 5;数字 4 的索引是 1;其余依此类推。

y <- c(4, 12, 6, 7, 2, 9, 5)
y[order(y)]

上述代码的输出如下:

2 4 5 6 7 9 12

这里通过索引对值进行了排序,实际值按升序打印。先用 order() 根据索引确定顺序,然后通过 y[some-value] 逐一取值。

在 order() 中使用不同参数对向量排序

我们看一个包含符号值 NA(缺失)的数据集示例。

order(x,na.last=TRUE)

x <- c(8, 2, 4, 1, -4, NA, 46, 8, 9, 5, 3)
order(x, na.last = TRUE)

上述代码的输出如下:

5 4 2 11 3 10 1 8 9 7 6

这里 order() 同样会按索引给出使数字升序排列的顺序。由于存在 NA,其索引会被放在最后,即索引 6 因 na.last=TRUE 而排在末尾。

order(x,na.last=FALSE)

order(x, na.last = FALSE)

上述代码的输出如下:

6 5 4 2 11 3 10 1 8 9 7

这里 order() 同样按索引给出升序顺序。由于存在 NA,其索引 6 因 na.last=FALSE 而被放在最前。

order(x,decreasing=TRUE,na.last=TRUE)

order(x, decreasing = TRUE, na.last = TRUE)

上述代码的输出如下:

7 9 1 8 10 3 11 2 4 5 6

此处由于 decreasing=TRUE,order() 会返回按索引对应的降序顺序:最大值 46 位于索引 7,其余值按降序排列。由于存在 NA,索引 6 因 na.last=TRUE 被放在最后。

order(x,decreasing=FALSE,na.last=FALSE)

order(x, decreasing = FALSE, na.last = FALSE)

上述代码的输出如下:

6 5 4 2 11 3 10 1 8 9 7

此处由于存在 NA 且其索引为 6,因 na.last=FALSE 被放在最前。由于 decreasing=FALSE,order() 返回升序顺序:最小值 -4 位于索引 5,其余值递增排列。

使用 order() 对数据框排序

我们来创建一个数据框,其中总体数量为 10。变量 gender 由向量值 'male' 和 'female' 构成,可使用 sample() 获取 10 个样本值,而 replace = TRUE 将只生成唯一值。类似地,age 的取值为 25 到 75,degree 的可能取值为 c("MA," "ME," "BE," "BSCS"),同样会生成唯一值。

任务:根据总体的年龄对给定数据按升序排序。

注意:您在本地运行时看到的示例数据可能不同,因为每次运行代码都会创建一个唯一的数据框。

population <- 10
gender <- sample(c("male", "female"), population, replace = TRUE)
age <- sample(25:75, population, replace = TRUE)
degree <- sample(c("MA", "ME", "BE", "BSCS"), population, replace = TRUE)
final_data <- data.frame(gender = gender, age = age, degree = degree)
final_data
genderagedegree
male40MA
female57BSCS
male66BE
female61BSCS
female48MA
male25MA
female49BE
male52ME
female57MA
female35MA

上述代码得到如下输出,展示了一个新创建的数据框。

  gender       age        degree
   male           40         MA
   female       57         BSCS
   male           66         BE
   female       61         BSCS
   female       48        MA
   male           25         MA
   female       49         BE
   male        52        ME
   female       57         MA
   female       35         MA

我们使用 order() 按变量 age 对数据框进行升序排序。

order(final_data$age)

上述代码的输出如下:

6 10 3 9 5 8 4 2 7 1

由于年龄 25 位于索引 6,其后是索引 10 的年龄 35,依此类推,所有与年龄相关的值按升序排列。

下面的代码通过带 [] 的排序索引按 age 升序排列,同时也会输出 gender 和 degree 信息。

final.data[order(final.data$age),]
 genderagedegree
6male25MA
10female35MA
1male40MA
5female48MA
7female49BE
8male52ME
2female57BSCS
9female57MA
4female61BSCS
3male66BE

上述代码的输出如下:

gender    age    degree
6    male    25    MA
10    female    35    MA
1    male    40    MA
5    female    48    MA
7    female    49    BE
8    male    52    ME
2    female    57    BSCS
9    female    57    MA
4    female    61    BSCS
3    male    66    BE

可以看到,age 已按升序排列,同时保留了对应的 gender 和 degree 信息。

使用 dplyr 的 arrange() 排序

若希望更易读、更现代化的写法,可以使用 dplyr 包中的 arrange() 函数。这在使用 tidyverse 生态时尤其有用:

# Install dplyr if needed: install.packages("dplyr")
library(dplyr)

# Sort by age in ascending order
final_data %>% arrange(age)

# Sort by age in descending order
final_data %>% arrange(desc(age))

# Sort by multiple columns
final_data %>% arrange(gender, desc(age))

arrange() 常用于数据分析流程,因为它能与 filter()、select()、mutate() 等 dplyr 函数通过管道操作符无缝集成。

排序方法对比

函数返回值最佳适用所属包
sort()已排序的值向量Base R
order()索引数据框、复杂排序Base R
arrange()排序后的数据框Tidyverse 工作流dplyr
setorder()就地修改大型数据集(内存高效)data.table

结语

在本教程中,我介绍了 R 中用于排序数据的关键方法:

  • sort():直接对向量排序
  • order():返回用于排序向量和数据框的索引
  • 通过 na.last 参数处理 NA 值
  • dplyr::arrange():用于数据框的现代、易读的排序方式
  • 多列排序以满足复杂的排序需求

更多信息请参阅order() 的官方 R 文档。

如果您想进一步学习 R,可以参加 DataCamp 的R 入门课程。您也可以查看我们的data.table 教程以进行高性能数据处理,或阅读我们关于R 中管道的指南来编写更整洁的代码。

主题