>我有几百个文件需要以复杂的方式对它们的列进行排序。想象一个字符向量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 拆分为不同的元素,然后使用mixedsort
从gtools
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)))