如何按多条件升序排序字符向量?基于指定子串数字及日期
R语言字符向量自定义排序实现方案
给定字符向量:
vec = c("aaa.bbb0bbb0.fff110321.csv", "aaa.bbb0bbb015.fff120321.csv", "aaa.bbb02bbb015.fff150321.csv","aaa.bbb02bbb015.fff130321.csv")
需要按以下优先级升序排序:
- 先看第一个
bbb后面的数字 - 再看第二个
bbb后面的数字 - 最后看字符串末尾的6位日期(格式为DDMMYY)
实现思路:提取排序关键字后排序
核心是把每个字符串里的三个排序字段提取出来,转成数值(避免字符串字典序的坑,比如"02"不会排在"0"前面),再用order()按优先级排序。
方法1:基础R写法
不需要额外依赖,用基础字符串处理函数:
# 提取第一个bbb后的数字 key1 <- as.numeric(sapply(strsplit(vec, "bbb"), function(x) x[2])) # 提取第二个bbb后的数字(取分割后第三部分的开头数字) key2 <- as.numeric(sapply(strsplit(vec, "bbb"), function(x) sub("\\..*", "", x[3]))) # 提取末尾的6位日期 key3 <- as.numeric(gsub(".*(\\d{6})\\.csv", "\\1", vec)) # 按优先级排序 sorted_vec <- vec[order(key1, key2, key3)]
方法2:tidyverse风格(更直观)
用stringr包简化正则提取,链式操作更清晰:
library(tidyverse) sorted_vec <- vec %>% # 转成数据框方便处理 enframe(name = NULL) %>% mutate( # 提取第一个bbb和第二个bbb之间的数字 key1 = as.numeric(str_extract(value, "(?<=bbb)\\d+(?=bbb)")), # 提取第二个bbb到.fff之间的数字 key2 = as.numeric(str_extract(value, "(?<=bbb\\d+bbb)\\d+(?=\\.fff)")), # 提取.csv前的6位日期 key3 = as.numeric(str_extract(value, "\\d{6}(?=\\.csv)")) ) %>% # 按优先级升序排列 arrange(key1, key2, key3) %>% # 提取排序后的原向量 pull(value)
最终排序结果
两种方法得到的结果一致:
[1] "aaa.bbb0bbb0.fff110321.csv" "aaa.bbb0bbb015.fff120321.csv" [3] "aaa.bbb02bbb015.fff130321.csv" "aaa.bbb02bbb015.fff150321.csv"
完全符合排序要求:
- 第一个
bbb后数字为0的两组排在02的两组前面 - 同key1下,key2为0的排在015前面
- 同key1和key2下,日期110321 < 120321,130321 < 150321
内容的提问来源于stack exchange,提问作者Flora Grappelli
相关产品推荐
相关产品推荐

