【问题标题】:How to replicate column-names, split them at delimiter '/', into multiple column-names, in R?如何在R中复制列名,在分隔符'/'处将它们拆分为多个列名?
【发布时间】:2015-07-22 01:50:28
【问题描述】:

我有这个矩阵(它的大小很大)“mymat”。我需要复制在“/”处匹配列名中具有“/”的列并制作“resmatrix”。我怎样才能在 R 中完成这项工作?

我的垫子

 a   b   IID:WE:G12D/V    GH:SQ:p.R172W/G   c
 1   3               4                  2   4
22   4               2                  2   4
 2   3               2                  2   4

resmatrix

 a   b   IID:WE:G12D   IID:WE:G12V    GH:SQ:p.R172W    GH:SQ:p.R172G   c
 1   3             4             4                2                2   4
22   4             2             2                2                2   4
 2   3             2             2                2                2   4

【问题讨论】:

    标签: regex r matrix string-parsing columnname


    【解决方案1】:

    找出哪些列有“/”并复制它们,然后重命名。要计算新名称,只需拆分 / 并将最后一个字母替换为第二个名称。

    # which columns have '/' in them?
    which.slash <- grep('/', names(mymat), value=T)
    new.names <- unlist(lapply(strsplit(which.slash, '/'),
           function (bits) {
             # bits[1] is e.g. IID:WE:G12D and bits[2] is the V
             # take bits[1] and replace the last letter for the second colname
             c(bits[1], sub('.$', bits[2], bits[1]))
           }))
    
    # make resmat by copying the appropriate columns
    resmat <- cbind(mymat, mymat[, which.slash])
    # order the columns to make sure the names replace properly
    resmat <- resmat[, order(names(resmat))]
    # put the new names in
    names(resmat)[grep('/', names(resmat))] <- sort(new.names)
    

    resmat 看起来像这样

    #    a b c GH:SQ:p.R172G GH:SQ:p.R172W IID:WE:G12D IID:WE:G12V
    # 1  1 3 4             2             2           4           4
    # 2 22 4 4             2             2           2           2
    # 3  2 3 4             2             2           2           2
    

    【讨论】:

      【解决方案2】:

      您可以使用grep 来获取带有/ ('nm1') 的列名的索引,通过使用sub/scan 创建'nm2' 来复制'nm1' 中的列名。然后,cbind 不是 'nm1' 的列,以及复制的列 ('nm1'),使用 'nm2' 更改列名,如果需要 order 列。

       #get the column index with grep
       nm1 <- grepl('/', names(df1))
       #used regex to rearrange the substrings in the nm1 column names
       #removed the `/` and use `scan` to split at the space delimiter
       nm2 <- scan(text=gsub('([^/]+)(.)/(.*)', '\\1\\2 \\1\\3', 
                 names(df1)[nm1]), what='', quiet=TRUE)
       #cbind the columns that are not in nm1, with the replicate nm1 columns 
       df2 <- cbind(df1[!nm1], setNames(df1[rep(which(nm1), each= 2)], nm2))
       #create another index to find the starting position of nm1 columns
       nm3 <- names(df1)[1:(which(nm1)[1L]-1)] 
       #we concatenate the nm3, nm2, and the rest of the columns to match 
       #the expected output order
       df2N <- df2[c(nm3, nm2, setdiff(names(df1)[!nm1], nm3))]
       df2N 
       #   a b IID:WE:G12D IID:WE:G12V GH:SQ:p.R172W GH:SQ:p.R172G c
       #1  1 3           4           4             2             2 4
       #2 22 4           2           2             2             2 4
       #3  2 3           2           2             2             2 4
      

      数据

      df1 <-  structure(list(a = c(1L, 22L, 2L), b = c(3L, 4L, 3L),
      `IID:WE:G12D/V` = c(4L, 
      2L, 2L), `GH:SQ:p.R172W/G` = c(2L, 2L, 2L), c = c(4L, 4L, 4L)),
      .Names = c("a", "b", "IID:WE:G12D/V", "GH:SQ:p.R172W/G", "c"),
      class = "data.frame", row.names = c(NA, -3L))
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-10-18
        • 2013-06-07
        • 2018-09-19
        • 2021-12-10
        • 1970-01-01
        • 1970-01-01
        • 2021-03-05
        相关资源
        最近更新 更多