You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在R语言中如何排序一列同时保留另一列的原有顺序?

解决R语言中按分组排序同时保留分组原始顺序的问题

这个需求其实很常见——你想要按每个region分组对year升序排列,但严格保留region在原始数据里的出现顺序(而不是按region的数值大小排序)对吧?之前用order或arrange没成功,应该是因为默认会按region的数值排序,忽略了它的原始出现顺序。我给你几种可行的方法:

1. 使用dplyr包(tidyverse风格)

这是最直观的方法,核心是先把region转换成因子,指定其levels为原始数据中region的唯一出现顺序,这样排序时就会遵循这个自定义顺序:

首先构造你的示例数据:

sales <- data.frame(
  year = c(2006,2006,2006,2006,2006,2007,2007,2007,2007,2007),
  region = c(1,101,107,11,13,1,101,107,11,13)
)

然后执行排序:

library(dplyr)

# 提取region的原始唯一出现顺序
region_original_order <- unique(sales$region)

sales_sorted <- sales %>%
  # 将region转为因子,指定levels为原始顺序
  mutate(region = factor(region, levels = region_original_order)) %>%
  # 先按region的自定义顺序排序,再按year升序
  arrange(region, year) %>%
  # 可选:如果需要将region转回整数类型(默认因子转整数会取levels的索引,所以要先转字符)
  mutate(region = as.integer(as.character(region)))

print(sales_sorted)

2. 使用Base R

如果你不想加载额外的包,可以用Base R的方法,通过match给每个region分配一个对应原始顺序的分组ID,再按这个ID和year排序:

# 提取region的原始唯一出现顺序
region_original_order <- unique(sales$region)
# 给每行数据分配对应原始顺序的分组ID
sales$group_id <- match(sales$region, region_original_order)
# 按分组ID和year排序,然后去掉临时的group_id列
sales_sorted_base <- sales[order(sales$group_id, sales$year), c("year", "region")]

print(sales_sorted_base)

3. 使用data.table包(高效处理大数据)

如果你处理的是大数据集,data.table的方法会更高效:

library(data.table)

setDT(sales)
# 直接通过match获取原始顺序的索引,再按该索引和year排序
sales_sorted_dt <- sales[order(match(region, unique(region)), year)]

print(sales_sorted_dt)

输出结果

以上三种方法都会得到你期望的结果:

year region
1  2006      1
2  2007      1
3  2006    101
4  2007    101
5  2006    107
6  2007    107
7  2006     11
8  2007     11
9  2006     13
10 2007     13

内容的提问来源于stack exchange,提问作者syoon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 15:52:39