【问题标题】:Split one column into several columns on basis of a separator in R [duplicate]根据R中的分隔符将一列分成几列[重复]
【发布时间】:2014-06-22 07:23:02
【问题描述】:

我有一个类似于here 的问题

如果我有如下数据结构:

 ROW_NO.        INPUT          STRAND
       1  1,888639,T,C             -1
       2  1,889158,G,C             NA                               
       3  1,889159,A,C             NA                                     
       4 1,978978,GC,G              1                                      
       5  1,982941,T,C             NA                                      
       6 1,1888193,C,A             -1

我需要做什么才能像这样拆分 INPUT 列:

 ROW_NO.        INPUT    Chrom     Position    Ref.y   Variant.y   
       1  1,888639,T,C    chr1       888639        T           C
       2  1,889158,G,C    chr1       889158        G           C                            
       3  1,889159,A,C    chr1       889159        A           C                                         
       4 1,978978,GC,G    chr1       978978       GC           G        
       5  1,982941,T,C    chr1       982941        T           C        
       6 1,1888193,C,A    chr1      1888193        C           A

我会将 STRAND 列保留在原来的位置,但不知何故,在格式化时,这里的一切都搞砸了,所以我把它省略了。

【问题讨论】:

    标签: string r split multiple-columns


    【解决方案1】:

    调用你的数据集df:

    library(stringr)
    result <- data.frame(df,do.call(rbind,str_split(df$INPUT,",")))
    result
    #   ROW_NO.         INPUT STRAND X1      X2 X3 X4
    # 1       1  1,888639,T,C     -1  1  888639  T  C
    # 2       2  1,889158,G,C     NA  1  889158  G  C
    # 3       3  1,889159,A,C     NA  1  889159  A  C
    # 4       4 1,978978,GC,G      1  1  978978 GC  G
    # 5       5  1,982941,T,C     NA  1  982941  T  C
    # 6       6 1,1888193,C,A     -1  1 1888193  C  A
    

    剩下的就是化妆品了:

    colnames(result)[4:7] <- c("Chrom","Position","Ref.y","Variant.y")
    result$Chrom <- paste0("chr",result$Chrom)
    

    编辑关于 cmets 的注释。

    建议的替代方案:

    result <- data.frame(df,do.call(rbind,strsplit(df$INPUT,",")))
    

    如果df$INPUT 是一个因素,则失败,它可能是也可能不是,这取决于您读取数据的方式。上面的解决方案,使用str_split(...),没有这个缺陷。

    【讨论】:

    • 我不确定 stringr 在这里添加了什么,因为 result &lt;- data.frame(d,do.call(rbind,strsplit(d$INPUT,","))) 仅使用 base 会得到相同的结果。
    • @Thomas,它增加了一些等待时间 :-)
    • 关于您的编辑,即使df$INPUT 是一个因素,使用strsplit(as.character(df$INPUT), ...) 仍然会更快。不幸的是,“stringr”中的一些函数以非常大的时间成本提供了便利,str_split 就是其中之一。
    • 我的建议是:data.frame(mydf, do.call(rbind, strsplit(as.character(mydf$INPUT), ",", fixed = TRUE)))fixed = TRUE 也将提供良好的速度提升。
    【解决方案2】:

    如果d 是您的数据框,您可以通过将read.csv 函数应用于INPUT 列来在基础中执行此操作:

    > out <- cbind(d, read.csv(text=d$INPUT, header=FALSE,
                               col.names=c('Chrom','Position','Ref.y','Variant.y')))
    > out
      ROW_NO.         INPUT STRAND Chrom Position Ref.y Variant.y
    1       1  1,888639,T,C     -1     1   888639     T         C
    2       2  1,889158,G,C     NA     1   889158     G         C
    3       3  1,889159,A,C     NA     1   889159     A         C
    4       4 1,978978,GC,G      1     1   978978    GC         G
    5       5  1,982941,T,C     NA     1   982941     T         C
    6       6 1,1888193,C,A     -1     1  1888193     C         A
    

    而且,就像@jlhoward 的回答一样,您可以使用pasteChrom 看起来像您想要的那样:

    out$Chrom <- paste0('chr',out$Chrom)
    

    【讨论】:

    • 我收到此错误:“textConnection(text) 中的错误:'text' 参数无效”
    • @soosus,这个错误是不言自明的。只需将d$INPUT 包裹在as.character 中,您的问题就会得到解决。
    【解决方案3】:

    我会从我的“splitstackshape”包中推荐concat.split

    library(splitstackshape)
    concat.split(mydf, "INPUT", ",")
    #   ROW_NO.         INPUT STRAND INPUT_1 INPUT_2 INPUT_3 INPUT_4
    # 1       1  1,888639,T,C     -1       1  888639       T       C
    # 2       2  1,889158,G,C     NA       1  889158       G       C
    # 3       3  1,889159,A,C     NA       1  889159       A       C
    # 4       4 1,978978,GC,G      1       1  978978      GC       G
    # 5       5  1,982941,T,C     NA       1  982941       T       C
    # 6       6 1,1888193,C,A     -1       1 1888193       C       A
    

    我正在开发一个更快的版本,目前是only at this Gist。最终,它将取代现有的concat.split 函数。

    cSplit(mydf, "INPUT", ",")
    #    ROW_NO. STRAND INPUT_1 INPUT_2 INPUT_3 INPUT_4
    # 1:       1     -1       1  888639       T       C
    # 2:       2     NA       1  889158       G       C
    # 3:       3     NA       1  889159       A       C
    # 4:       4      1       1  978978      GC       G
    # 5:       5     NA       1  982941       T       C
    # 6:       6     -1       1 1888193       C       A
    

    【讨论】:

      猜你喜欢
      • 2021-08-31
      • 1970-01-01
      • 1970-01-01
      • 2021-08-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多