iT邦幫忙

2019 iT 邦幫忙鐵人賽

0
自我挑戰組

When Bioinfo met Julia: Bioinformatician的30天Julia學習之路系列 第 32

用Julia將一個Genome按照某個window size切並計算GC content

  • 分享至 

  • xImage
  •  

緣起

我在BioJulia裡頭找不到類似R語言裡頭Biostrings那個package所提供的letterFrequencyInSlidingView,所以就打算來自幹一個。

所需工具

在我自幹的初淺版本當中,會需要用到的packages有:

  • BioSequences.jl
  • DataFrames.jl

先寫個針對每個序列計算GC content的函數

"""
在這個函數中,我需要用到四個變數:
  - seq是BioSequence{DNAAlphabet{4}}類別的物件
  - windowSize是我所想要設定的window大小的Int類別整數變數
  - asProb則是決定是否將計算得到的GC數量轉化成比例的布林變數
  - seqName則是染色體或其他用來代表該序列名稱的String類別變數
"""

function getGCcontentInSlideWindowView(seq::BioSequence{DNAAlphabet{4}}, windowSize::Int, asProb::Bool, seqName::String)
	inputSeqLen = length(seq)
	@assert inputSeqLen >= windowSize
	restSeqLen = inputSeqLen % windowSize
	windowsNum = restSeqLen == 0 ? inputSeqLen ÷ windowSize : inputSeqLen ÷ windowSize + 1
	GCcontent = asProb ? zeros(Float32, windowsNum) : zeros(Int32, windowsNum)
	StartPos = zeros(Int32, windowsNum)
	StopPos = zeros(Int32, windowsNum)
	Chromosome = fill(seqName, windowsNum)
	for i = 0:(windowsNum-1)
		idx = i + 1
		start = i * windowSize + 1
		stop = restSeqLen == 0 ? (i + 1) * windowSize : 
		                         ( i == (windowsNum - 1) ? i * windowSize + restSeqLen : (i+1) * windowSize)
		StartPos[idx] = start
		StopPos[idx] = stop
		if i == (windowsNum - 1)
			@assert stop == inputSeqLen
		end
		subseq = seq[start:stop]
		actgComposition = BioSequences.Composition(subseq).counts
		numG = haskey(actgComposition, DNA_G) ? actgComposition[DNA_G] : 0
		numC = haskey(actgComposition, DNA_C) ? actgComposition[DNA_C] : 0
		numGC = numG + numC
		GCcontent[idx] = asProb ? round(numGC/windowSize, digits = 4) : numGC
	end
	output = DataFrame(Chrom = Chromosome, Start = StartPos, Stop = StopPos, GC = GCcontent)
	return output
end

拿個實際的例子來看看

using BioSequences
using DataFrame

# 建立一個空表格
gcData = DataFrame([String, Int32, Int32, Float32], [:Chrom, :Start, :Stop, :GCcontent], 0)

# 讀取人類基因體資料
reader = FASTA.Reader(open("human.fa", "r"))

# 設定window size為20kbp, 開始計算GC content
i = 1
for rec in reader
    seqname = FASTA.identifier(rec)
    seq = FASTA.sequence(rec)
    dataFromEachChrom = getGCcontentInSlideWindowView(seq, 20000, true, seqname)
    global gcData = vcat(gcData, dataFromEachChrom)
    global i += 1
    
    ## 不想計算Mitochodria的部份154423×4 DataFrame
    if i == 25
        break
    end
end
close(reader)

執行後可以得到

154423×4 DataFrame
│ Row    │ Chrom  │ Start    │ Stop     │ GC      │
│        │ String │ Int32    │ Int32    │ Float32 │
├────────┼────────┼──────────┼──────────┼─────────┤
│ 1      │ chr1   │ 1200000.2962  │
│ 2      │ chr1   │ 20001400000.4943  │
│ 3      │ chr1   │ 40001600000.3608  │
│ 4      │ chr1   │ 60001800000.3566  │
│ 5      │ chr1   │ 800011000000.4026  │
│ 6      │ chr1   │ 1000011200000.377   │
│ 7      │ chr1   │ 1200011400000.471   │
│ 8      │ chr1   │ 1400011600000.448   │
⋮
│ 154415 │ chrY   │ 57060001570800000.4089  │
│ 154416 │ chrY   │ 57080001571000000.3796  │
│ 154417 │ chrY   │ 57100001571200000.3872  │
│ 154418 │ chrY   │ 57120001571400000.4013  │
│ 154419 │ chrY   │ 57140001571600000.417   │
│ 154420 │ chrY   │ 57160001571800000.4346  │
│ 154421 │ chrY   │ 57180001572000000.5268  │
│ 154422 │ chrY   │ 57200001572200000.4822  │
│ 154423 │ chrY   │ 57220001572274150.0

是不是也很容易呢?


上一篇
[Day 30] 疑?最後一天了,來看看怎麼使用Julia爬蟲好了
系列文
When Bioinfo met Julia: Bioinformatician的30天Julia學習之路32
.

1 則留言

0
yingwenshuzi
iT邦新手 5 級 ‧ 2019-02-14 13:03:46

我运行 seq = FASTA.sequence(rec) 这步非常慢,有没有比较便捷的方法取出特定位置的序列,比如seq = FASTA.sequence(rec, 500000:500010)呢?谢谢!

我要留言

立即登入留言