2015-05-26 24 views
5

Tôi có một dataframe (TBB) như sauTìm biểu thức chính quy trong một cột và thêm vào một cột mới trong cùng một dataframe

X.CHROM POS  INFO 

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

Tôi muốn trích xuất tất cả mọi thứ giữa mỗi dấu chấm phẩy và đặt nó trong cột riêng của mình do đó kết quả sẽ trông giống như

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 

tôi cố gắng này

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

nhưng các cột là sai kích thước tương đối với nhau và rõ ràng tôi sẽ phải lặp lại điều này cho mỗi từ sau dấu chấm phẩy vì vậy không hiệu quả lắm.

Trả lời

6

Bạn có thể thử 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 
+0

và Người viết chủ đề - Tôi cần giải pháp tương tự vào cuối tuần trước (nhưng đặt nó ở trạng thái giữ do kỳ nghỉ) , cảm ơn! Tuy nhiên, trong bài viết gốc có 4 "mục" ở giữa các dấu chấm phẩy trong hàng với '3334', trong khi các hàng khác có 3. Điều đó có phá vỡ tính tổng quát không? –

+1

@AlexeyFerapontov nó sẽ không phanh, nhưng nó sẽ tạo ra một mục riêng biệt cho '.' nếu đó là những gì bạn có ý nghĩa. Mặc dù điều đó có thể cũng được xử lý với một regex thích hợp tôi đoán. –

+2

Tuyệt vời! Cảm ơn bạn! –

2

Bạn cũng có thể thử tốt cũ plyr::rbind.fill hoặc dplyr::rbind_list kết hợp với strsplit:

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

Hoặc bạn có thể sử dụng cSplit từ splitstackshape

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

Bạn có thể thử các gói base từ thư viện 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 
+0

Tôi cứ quên tùy chọn R cơ bản đơn giản – akrun

0

Sử dụng data.table v1.9.5+:

require(data.table) 
setDT(dat)[, paste0("INFO", 1:4) := tstrsplit(INFO, ";", fixed=TRUE)] 
Các vấn đề liên quan