R语言按指定样本类型排序dataframe 保留ID及分装编号原顺序
自定义顺序排序DataFrame实现方案
需求说明
- 保持各样本类型分组下
ID、Aliquot Number的原有相对顺序不变 - 按照
sample type字段对数据集排序,排序规则为指定顺序:S,B,E,N,而非默认字母序 - 原始数据与预期排序后的数据结构如下
原始数据(Original Data)
original_df <- structure(list(ID = c("0226", "0226", "0226", "0226", "0226", "0226", "0226", "0226", "0226", "0226", "0226", "0226", "0226", "0226", "0226", "0226", "0226", "0226", "0053", "0053", "0053", "0053", "0053", "0053", "0053", "0053", "0053", "0053", "0053", "0053", "0053", "0053", "0053", "0053", "0053", "0053", "0053", "0053"), `Unique Aliquot ID` = c("C0226BCV1B 01", "C0226BCV1B 02", "C0226BCV1S 01", "C0226BCV1S 02", "C0226BCV1S 03", "C0226BCV1S 04", "C0226BCV1S 05", "C0226BCV1S 06", "C0226BCV1S 07", "C0226BCV1E 01", "C0226BCV1E 02", "C0226BCV1E 03", "C0226BCV1E 04", "C0226BCV1E 05", "C0226BCV1E 06", "C0226BCV1N 01", "C0226BCV1N 02", "C0226BCV1N 03", "C0053BCV1B 01", "C0053BCV1B 02", "C0053BCV1S 01", "C0053BCV1S 02", "C0053BCV1S 03", "C0053BCV1S 04", "C0053BCV1S 05", "C0053BCV1S 06", "C0053BCV1S 07", "C0053BCV1S 08", "C0053BCV1N 01", "C0053BCV1N 02", "C0053BCV1N 03", "C0053BCV1E 01", "C0053BCV1E 02", "C0053BCV1E 03", "C0053BCV1E 04", "C0053BCV1E 05", "C0053BCV1E 06", "C0053BCV1E 07" ), `sample type` = c("B", "B", "S", "S", "S", "S", "S", "S", "S", "E", "E", "E", "E", "E", "E", "N", "N", "N", "B", "B", "S", "S", "S", "S", "S", "S", "S", "S", "N", "N", "N", "E", "E", "E", "E", "E", "E", "E"), `Aliquot Number` = c(1, 2, 1, 2, 3, 4, 5, 6, 7, 1, 2, 3, 4, 5, 6, 1, 2, 3, 1, 2, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 1, 2, 3, 4, 5, 6, 7)), row.names = c(NA, -38L), class = c("tbl_df", "tbl", "data.frame"))
预期排序结果(Intended Data)
intended_df <- structure(list(ID = c("0226", "0226", "0226", "0226", "0226", "0226", "0226", "0226", "0226", "0226", "0226", "0226", "0226", "0226", "0226", "0226", "0226", "0226", "0053", "0053", "0053", "0053", "0053", "0053", "0053", "0053", "0053", "0053", "0053", "0053", "0053", "0053", "0053", "0053", "0053", "0053", "0053", "0053"), `Unique Aliquot ID` = c("C0226BCV1S 01", "C0226BCV1S 02", "C0226BCV1S 03", "C0226BCV1S 04", "C0226BCV1S 05", "C0226BCV1S 06", "C0226BCV1S 07", "C0226BCV1B 01", "C0226BCV1B 02", "C0226BCV1E 01", "C0226BCV1E 02", "C0226BCV1E 03", "C0226BCV1E 04", "C0226BCV1E 05", "C0226BCV1E 06", "C0226BCV1N 01", "C0226BCV1N 02", "C0226BCV1N 03", "C0053BCV1S 01", "C0053BCV1S 02", "C0053BCV1S 03", "C0053BCV1S 04", "C0053BCV1S 05", "C0053BCV1S 06", "C0053BCV1S 07", "C0053BCV1S 08", "C0053BCV1B 01", "C0053BCV1B 02", "C0053BCV1E 01", "C0053BCV1E 02", "C0053BCV1E 03", "C0053BCV1E 04", "C0053BCV1E 05", "C0053BCV1E 06", "C0053BCV1E 07", "C0053BCV1N 01", "C0053BCV1N 02", "C0053BCV1N 03" ), `sample type` = c("S", "S", "S", "S", "S", "S", "S", "B", "B", "E", "E", "E", "E", "E", "E", "N", "N", "N", "S", "S", "S", "S", "S", "S", "S", "S", "B", "B", "E", "E", "E", "E", "E", "E", "E", "N", "N", "N"), `Aliquot Number` = c(1, 2, 3, 4, 5, 6, 7, 1, 2, 1, 2, 3, 4, 5, 6, 1, 2, 3, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 1, 2, 3, 4, 5, 6, 7, 1, 2, 3)), row.names = c(NA, -38L), class = c("tbl_df", "tbl", "data.frame"))
实现代码
核心逻辑:将sample type转换为自定义水平顺序的因子类型,再配合稳定排序,即可在不打乱组内原有行顺序的前提下,按指定优先级排序。
方法1:dplyr实现(适配tibble格式,代码更简洁)
library(dplyr) # 定义样本类型的目标排序顺序 type_levels <- c("S", "B", "E", "N") sorted_data <- original_df %>% mutate(`sample type` = factor(`sample type`, levels = type_levels)) %>% arrange(ID, `sample type`) # 验证结果是否和预期一致,返回TRUE即为正确 identical(sorted_data, intended_df)
方法2:base R实现(无需加载第三方包)
# 定义样本类型的目标排序顺序 type_levels <- c("S", "B", "E", "N") # 生成排序索引:先按ID排序,再按自定义顺序的sample type排序 sort_idx <- order(original_df$ID, factor(original_df$`sample type`, levels = type_levels)) sorted_data <- original_df[sort_idx, ] # 验证结果 identical(sorted_data, intended_df)
说明:两种方法用到的排序函数均为稳定排序,同一ID、同一样本类型分组内的行,会完全保留原始数据中
Aliquot Number的先后顺序,不会出现组内乱序的问题。
内容的提问来源于stack exchange,提问作者JBrowne13
相关产品推荐
相关产品推荐

