在一列中查找正则表达式并添加到同一数据框中的新列

时间:2015-05-26 13:46:39

标签: r

我有一个数据帧(TBB)如下

X.CHROM    POS        INFO

 chr1     134324   SAMPLE=LNGHJ;
 chr2     2333     SAMPLE=dd;GERP;.;
 chr2      3334     SAMPLE=;GERP;DDS;CDC=dd;

我想在每个分号之间提取所有内容并将其放在自己的列中,以便结果看起来像

X.CHROM    POS        INFO                       
chr1     134324       SAMPLE=LNGHJ;            SAMPLE=LNGHJ    
chr2     2333         SAMPLE=dd;GERP;DDS=3;    SAMPLE=dd       GERP   DDS=3   
chr2      3334        SAMPLE=;GERP;DDS;        SAMPLE=         GERP   DDS

我试过这个

TBB3 <- TBB[grep("SAMPLE.*?;", TBB$INFO), ]
TBB4<-cbind(TBB3,TBB)

但是相对于彼此的列的大小是错误的,显然我必须在分号之后为每个单词重复这个,所以效率不高。

5 个答案:

答案 0 :(得分:6)

您可以尝试stringi::stri_split_fixed

library(stringi)
cbind(TBB, stri_split_fixed(TBB$INFO, ";", simplify = TRUE, omit_empty = TRUE))
#   X.CHROM    POS                  INFO            1    2     3
# 1    chr1 134324         SAMPLE=LNGHJ; SAMPLE=LNGHJ           
# 2    chr2   2333 SAMPLE=dd;GERP;DDS=3;    SAMPLE=dd GERP DDS=3
# 3    chr2   3334     SAMPLE=;GERP;DDS;      SAMPLE= GERP   DDS

答案 1 :(得分:2)

您还可以尝试将plyr::rbind.filldplyr::rbind_liststrsplit结合使用:

cbind(TBB, 
      do.call(dplyr::rbind_list, 
              lapply(strsplit(as.character(TBB$INFO), split = ";", fixed = TRUE), 
                     function(x) 
                       as.data.frame(t(x), stringsAsFactors = F))
              )
)
#   X.CHROM    POS                     INFO           V1   V2   V3     V4
# 1    chr1 134324            SAMPLE=LNGHJ; SAMPLE=LNGHJ <NA> <NA>   <NA>
# 2    chr2   2333        SAMPLE=dd;GERP;.;    SAMPLE=dd GERP    .   <NA>
# 3    chr2   3334 SAMPLE=;GERP;DDS;CDC=dd;      SAMPLE= GERP  DDS CDC=dd

答案 2 :(得分:2)

或者您可以使用cSplit

中的splitstackshape
library(splitstackshape)
cSplit(TBB, 'INFO', ';', drop=FALSE)

答案 3 :(得分:1)

您可以尝试base库中的R包:

dd <- read.table(header = TRUE, text = "X.CHROM    POS        INFO
chr1     134324   SAMPLE=LNGHJ;
chr2     2333     SAMPLE=dd;GERP;.;
chr2      3334     SAMPLE=;GERP;DDS;CDC=dd;")


(dd1 <- read.table(text = as.character(dd$INFO), sep = ';', fill = NA,
                   na.strings = c('', '.','NA')))

#             V1   V2   V3     V4 V5
# 1 SAMPLE=LNGHJ <NA> <NA>   <NA> NA
# 2    SAMPLE=dd GERP <NA>   <NA> NA
# 3      SAMPLE= GERP  DDS CDC=dd NA

cbind(dd, dd1[, -ncol(dd1)])

#     X.CHROM    POS                     INFO           V1   V2   V3     V4
#   1    chr1 134324            SAMPLE=LNGHJ; SAMPLE=LNGHJ <NA> <NA>   <NA>
#   2    chr2   2333        SAMPLE=dd;GERP;.;    SAMPLE=dd GERP <NA>   <NA>
#   3    chr2   3334 SAMPLE=;GERP;DDS;CDC=dd;      SAMPLE= GERP  DDS CDC=dd

答案 4 :(得分:0)

使用data.table v1.9.5+

require(data.table)
setDT(dat)[, paste0("INFO", 1:4) := tstrsplit(INFO, ";", fixed=TRUE)]