通过colnames

时间:2018-02-01 09:08:58

标签: r bioinformatics genetics

我有一个这样的数据框:

           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

如果有人知道它会很棒。

3 个答案:

答案 0 :(得分:4)

一个选项是提取数字部分以及最后的子字符串,然后执行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"))

答案 1 :(得分:3)

我猜您的数据来自遗传学并且看起来相当标准,所有变体的 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))))]

答案 2 :(得分:2)

使用dplyr的简单解决方案:

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

这可能是比@ akrun的答案更少(复杂)的代码,但只适用于您想订购少量列的时候。