按列名排序数据框

Order dataframe by colnames

我有一个这样的数据框:

           G2_ref G10_ref G12_ref G2_alt G10_alt G12_alt
20011953      3      6      0      5       1     5    
12677336      0      0      0      1       3     6  
20076754      0      3      0     12      16     8 
2089670       0      4      0      1      11     9
9456633       0      2      0      3      10     0 
468487        0      0      0      0       0     0

我正在尝试对列进行排序以最终获得此列顺序:

G2_ref G2_alt G10_ref G10_alt G12_ref G12_alt

我试过了:df[,order(colnames(df))]

但是我有这个订单:

G10_alt G10_ref G12_alt G12_ref G2_alt G2_ref

如果有人有任何想法那就太好了。

一个选择是提取数字部分以及末尾的子字符串,然后执行 order

df[order(as.numeric(gsub("\D+", "", names(df))), 
            factor(sub(".*_", "", names(df)), levels = c('ref', 'alt')))]
#          G2_ref G2_alt G10_ref G10_alt G12_ref G12_alt
#20011953      3      5       6       1       0       5
#12677336      0      1       0       3       0       6
#20076754      0     12       3      16       0       8
#2089670       0      1       4      11       0       9
#9456633       0      3       2      10       0       0
#468487        0      0       0       0       0       0

数据

df <- structure(list(G2_ref = c(3L, 0L, 0L, 0L, 0L, 0L), G10_ref = c(6L, 
0L, 3L, 4L, 2L, 0L), G12_ref = c(0L, 0L, 0L, 0L, 0L, 0L), G2_alt = c(5L, 
1L, 12L, 1L, 3L, 0L), G10_alt = c(1L, 3L, 16L, 11L, 10L, 0L), 
    G12_alt = c(5L, 6L, 8L, 9L, 0L, 0L)), .Names = c("G2_ref", 
"G10_ref", "G12_ref", "G2_alt", "G10_alt", "G12_alt"), 
   class = "data.frame", row.names = c("20011953", 
"12677336", "20076754", "2089670", "9456633", "468487"))

使用 dplyr 的简单解决方案:

library(dplyr)
df <- df %>%
      select(G2_ref, G2_alt, G10_ref, G10_alt, G12_ref, G12_alt)

也许这比@akrun 的答案更少(复杂)代码,但仅适用于您想要订购少量列的情况。

我猜你的数据来自遗传学,看起来很标准,第一列是所有变体的 ref 等位基因,然后是 alt所有变体的等位基因。

意味着我们可以从你的 数据帧 的一半使用 alternated column index,即:我们将尝试创建这个索引 - c(1, 4, 2, 5, 3, 6) 然后子集:

ix <- c(rbind(seq(1, ncol(df1)/2), seq(ncol(df1)/2 + 1, ncol(df1))))
ix
# [1] 1 4 2 5 3 6

df1[, ix]
#          G2_ref G2_alt G10_ref G10_alt G12_ref G12_alt
# 20011953      3      5       6       1       0       5
# 12677336      0      1       0       3       0       6
# 20076754      0     12       3      16       0       8
# 2089670       0      1       4      11       0       9
# 9456633       0      3       2      10       0       0
# 468487        0      0       0       0       0       0

# or all in one line
df1[, c(rbind(seq(1, ncol(df1)/2), seq(ncol(df1)/2 + 1, ncol(df1))))]