基于mixedorder实现data.table多列动态混合排序需求
动态列名结合mixedorder实现data.table自然排序
问题背景
现有包含字符、数字混合类型数据的data.table,需要根据**动态输入的列名(数量1个及以上)**进行多层级自然排序。要求必须使用mixedorder(因setorderv排序结果不符合预期),禁止转换为data.frame或使用dplyr包。
样本数据1
library(data.table) library(gtools) patients = c("1A","10A","11A","2B","2C","22C","3A","3B","A1","2"); study= c("1a",2,3,4,5,6,7,8,1,1); treatment = c("10mg","1mg","2g","3mcg","6mcg","a","a","b","f",5); DT = data.table(study,patients,treatment);
动态列输入示例
input = c("study","patients");
补充验证样本数据2
DT<-data.table(values = c(rnorm(100),2:11), sortcol1 = c(paste0("ASORT", sample(1:100, 100, replace = TRUE)),1:10), sortcol2 = c(paste0("BSORT", sample(1:100, 100, replace = TRUE)),5:14), stringsAsFactors = F) input = c("sortcol2","sortcol1");
解决方案
利用do.call将动态列名对应的列作为参数传递给mixedorder,实现动态多层排序:
# 执行动态排序 sorted_DT <- DT[do.call(mixedorder, c(DT[, ..input], list(decreasing = FALSE)))]
代码解释
DT[, ..input]:data.table特有的语法,用于提取input向量指定的所有列,返回一个data.table对象do.call(mixedorder, ...):将提取出的列作为位置参数传递给mixedorder,同时传入decreasing参数控制排序方向- 最终通过
DT[排序索引]得到按指定列自然排序后的结果
该方法支持任意数量的动态排序列,且完全遵循mixedorder的自然排序逻辑,解决了setorderv对混合类型列排序不符合预期的问题。
内容的提问来源于stack exchange,提问作者Mohit
相关产品推荐
相关产品推荐

