R 正则表达式,用于字符向量的奇数排序



>我有几百个文件需要以复杂的方式对它们的列进行排序。想象一个字符向量x它是names(foo)的结果,其中foo是一个data.frame

x <- c("x1","i2","Component.1","Component.10","Component.143","Component.13",
"r4","A","C16:1n-7")

我想根据以下规则对其进行排序:首先,以"组件"开头的任何内容按字母顺序排列。其次,以字母顺序排列以"C"和数字开头的任何剩余内容。第三,按字母顺序排列。

对于x,这将是:

x[c(3,4,6,5,9,8,2,7,1)]

这是一项regexp任务吗?有人使用match吗?每个文件将具有不同数量的列(因此x列的长度将不同(。任何提示表示赞赏。

您可以使用base-r中的函数order来实现这一点:

x <- c("x1","i2","Component.1","Component.10","Component.143","Component.13",
"r4","A","C16:1n-7")    
order(
!startsWith(x, "Component"), # 0 - starts with component, 1 - o.w.
!grepl("^C\d", x),          # 0 - starts with C<NUMBER>, 1 - o.w.
x                            # alphabetical
)
# output: 3 4 6 5 9 8 2 7 1

仅使用基本 R 的暴力解决方案:

first = sort(x[grepl('^Component', x)])
second = sort(x[grepl('^C\d', x)])
third = sort(setdiff(x, c(first, second)))
c(first, second, third)

我们可以将 int 拆分为不同的元素,然后使用mixedsortgtools

v1 <-  c(gtools::mixedsort(grep("Component", x, value = TRUE)), 
gtools::mixedsort(grep("^C\d+", x, value = TRUE)))
c(v1, gtools::mixedsort(x[!x %in% v1]))
#[1] "Component.1"   "Component.10"  "Component.13"  "Component.143" "C16:1n-7"      "A"             "i2"            "r4"           
#[9] "x1"   

或者select假设这些是 data.frame 的列的另一个选项

library(dplyr)
df1 %>%
select(mixedsort(starts_with('Component')), 
mixedsort(names(.)[matches("^C\d+")]), 
gtools::mixedsort(names(.)[everything()]))

如果只是出现的顺序

df1 %>% 
select(starts_with('Component'), matches('^C\d+'), sort(names(.)[everything()]))

数据

set.seed(24)
df1 <- as.data.frame(matrix(rnorm(5 * 9), ncol = 9,
dimnames = list(NULL, x)))

最新更新