[英]R: Splitting up a “:” delimited VCF file, using a 'for-loop' (iterating over several columns) to create multiple matrices
我為什么要問這個?
似乎很多人在拆分VCF文件和使用for循環遍歷列時都遇到問題,但是我沒有遇到任何與使用包含多個示例的VCF文件相關的方法來解決這兩個問題-將會解釋。
這是數據結構的示例 :
Loci Sample1
[1] 0/1:15:55:54:49:5:9.26%:2.8371E-2:37:36:49:0:5:0
[2] 0/1:42:55:53:40:13:24.53%:5.2873E-5:34:37:40:0:13:0
[3] 0/1:15:54:54:49:5:9.26%:2.8371E-2:35:33:49:0:5:0
問題是如何在許多位點(行)和多個樣本(列)上創建具有許多輸出統計信息(每個均由“:”分隔)的直觀表?
我已經設法解決了這個問題的一半 :
我開發了一個R腳本,該腳本可以從單個示例列中獲取信息,並輸出一個將每個單獨的統計信息分開的矩陣。 代碼如下:
data <- vcf.small
# First, create a list representing each row (locus) and separate the
# statistics; second, breakdown the list's structure but maintain data order.
split1 <-strsplit(as.character(data$Sample1),":")
split2 <- unlist(split1)
# Create a matrix: here, there are 14 values by 3 loci.
mtx1a <- matrix(split2, ncol=14, nrow=3, dimnames=list(NULL,c("GT","GQ","SDP","DP","RD","AD","FREQ","PVAL","RBQ","ABQ","RDF","RDR","ADF","ADR")), byrow=TRUE)
# Create some additional variables (columns) to add to the matrix.
sample <- matrix(rep(1,3), ncol=1, nrow=3, dimnames=list(NULL,c("SAMPLE")))
locus <- matrix(1:3, ncol=1, nrow=3, dimnames=list(NULL,c("LOCUS")))
# Add them to the matrix.
mtx1b <- cbind(mtx1a,sample)
mtx1b <- cbind(mtx1b,locus)
Voila,輸出:
GT GQ SDP DP RD AD FREQ PVAL RBQ ABQ RDF RDR ADF ADR SAMPLE LOCUS
[1,] "0/1" "15" "55" "54" "49" "5" "9.26%" "2.8371E-2" "37" "36" "49" "0" "5" "0" "1" "1"
[2,] "0/1" "42" "55" "53" "40" "13" "24.53%" "5.2873E-5" "34" "37" "40" "0" "13" "0" "1" "2"
[3,] "0/1" "15" "54" "54" "49" "5" "9.26%" "2.8371E-2" "35" "33" "49" "0" "5" "0" "1" "3"
“循環”問題 :
輸出是完美的,但是現在我無法解決這個問題,我不知道該如何創建一個包含以上代碼的for循環,以便為每個樣本創建單獨的矩陣。 我說:
for(i in names(data){
split[i] <-strsplit(as.character(data$[i]),":")
split[i] <- unlist(split[i])
mtx[i]a <- matrix(split2, ncol=14, nrow=3,
[etc etc..]
}
問題是我需要創建自定義的單個變量來為每個樣本(即列)設置每個矩陣。 但是,R不會將[i]用作占位符,其中i =樣本(/列)名稱。
理想情況下,每個樣本(/列)特定的變量應讀為:“ splitSample1”,“ splitSample2”,“ splitSample3”等。這主要是為了允許for循環處理所有列,而不必重新創建針對每個列的代碼列名。 我猜我想做的是從Linux重新創建“ $ i”語法,但是顯然在這里不起作用。
解決此問題將使處理非常大的數據集更加容易管理,我確實嘗試了尋找解決方法。 任何幫助深表感謝!
我認為最好將結果存儲在data.frame
或data.table
,因為每個拆分列的class
類型都不同。 matrix
只能存儲一個類。 如果只有一個character
列,則該類將成為所有columns
character
。
使用data.table
的devel
版本,我們可以使用tstrsplit
拆分為列,並使用type.convert=TRUE
更改class
。 開發版本可以從here
安裝
library(data.table)#v1.9.5+
nm1 <- c('GT', 'GQ', 'SDP', 'DP', 'RD', 'AD', 'FREQ', 'PVAL', 'RBQ',
'ABQ', 'RDF', 'RDR', 'ADF', 'ADR')
setDT(data)[, (nm1):=tstrsplit(Sample1, ':', type.convert=TRUE)][,
Sample1:=NULL][, c('sample', 'locus'):= list(1, 1:3)][]
# GT GQ SDP DP RD AD FREQ PVAL RBQ ABQ RDF RDR ADF ADR sample locus
#1: 0/1 15 55 54 49 5 9.26% 2.8371e-02 37 36 49 0 5 0 1 1
#2: 0/1 42 55 53 40 13 24.53% 5.2873e-05 34 37 40 0 13 0 1 2
#3: 0/1 15 54 54 49 5 9.26% 2.8371e-02 35 33 49 0 5 0 1 3
如果數據集中有多個“樣本”列,我們可以使用lapply
遍歷這些列,並在列表中創建拆分數據集(“ lst”)。
nm2 <- paste0('splitSample', 1:ncol(data2))
lst <- setNames(
lapply(seq_len(ncol(data2)), function(i)
setDT(list(data2[,i]))[, (nm1) := tstrsplit(V1, ":",
type.convert=TRUE)][, V1:=NULL][,
c('sample', 'locus'):= list(i, 1:.N)]),
nm2)
在“列表”中工作會更容易,但是如果我們需要在全局環境中使用單獨的數據集對象(不推薦),則可以使用list2env
。
list2env(lst, envir=.GlobalEnv)
splitSample1
# GT GQ SDP DP RD AD FREQ PVAL RBQ ABQ RDF RDR ADF ADR sample locus
#1: 0/1 15 55 54 49 5 9.26% 2.8371E-2 37 36 49 0 5 0 1 1
#2: 0/1 42 55 53 40 13 24.53% 5.2873E-5 34 37 40 0 13 0 1 2
#3: 0/1 15 54 54 49 5 9.26% 2.8371E-2 35 33 49 0 5 0 1 3
splitSample2
# GT GQ SDP DP RD AD FREQ PVAL RBQ ABQ RDF RDR ADF ADR sample locus
#1: 0/2 15 55 55 49 5 10.26% 2.971E-2 37 32 49 0 5 0 2 1
#2: 0/2 52 55 53 40 13 22.53% 1.2873E-5 34 37 12 0 13 0 2 2
#3: 0/2 17 54 54 49 18 9.29% 3.8371E-2 42 33 49 0 5 0 2 3
注意:在這里,我將輸入數據集用作data.frame。
data <- structure(list(Sample1 =
c("0/1:15:55:54:49:5:9.26%:2.8371E-2:37:36:49:0:5:0",
"0/1:42:55:53:40:13:24.53%:5.2873E-5:34:37:40:0:13:0",
"0/1:15:54:54:49:5:9.26%:2.8371E-2:35:33:49:0:5:0"
)), .Names = "Sample1", class = "data.frame", row.names = c(NA, -3L))
data2 <- structure(list(Sample1 =
c("0/1:15:55:54:49:5:9.26%:2.8371E-2:37:36:49:0:5:0",
"0/1:42:55:53:40:13:24.53%:5.2873E-5:34:37:40:0:13:0",
"0/1:15:54:54:49:5:9.26%:2.8371E-2:35:33:49:0:5:0"
), Sample2 = c("0/2:15:55:55:49:5:10.26%:2.971E-2:37:32:49:0:5:0",
"0/2:52:55:53:40:13:22.53%:1.2873E-5:34:37:12:0:13:0",
"0/2:17:54:54:49:18:9.29%:3.8371E-2:42:33:49:0:5:0")),
.Names = c("Sample1", "Sample2"), class = "data.frame",
row.names = c(NA, -3L))
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.