昨天我以最近正在處理的其中一種資料作為這次鐵人賽挑戰的第一個範例,其中主要得先靠著parse某一個資料表格後,抽取出我需要的資料,再使用BioSequences這個package將目標序列輸出。一開始讀取、處理表格資料的部份,我所使用的Packages為CSV+DataFrames。Data Frame
這種表格類資料在當前各領域中的資料科學分析中實為最常見的其中一種,當然在生命科學領域也少不了看到這種格式的資料,從昨天提到的Genotyping array、基因表現量到各種註解資訊(annotation information),這些記載了各種資訊的表格不僅讓我們能夠很容易、直觀地查找我們關心的數據,還可以很容易地通過資料庫工具儲存、處理及分析,所以在生物資訊領域大概是除了基因序列外,最常處理的一種資料格式了。因此要使用Julia來處理這種資料,我就選擇了DataFrames
跟CSV
這兩個發展已經相當成熟的packages來使用。當然啦,如果你習慣像我以前認識的某些喜歡土法煉鋼的人專門用二維陣列來處理這類數據,我也是不會反對的,畢竟這年代還是有人堅持地心說、堅持地球是平的,人總得學習接納不同的想法。
DataFrames
及CSV
要安裝前面提到的兩個packages很簡單,直接透過Pkg.add()
這個函數安裝即可:
using Pkg
required_pkgs = ["DataFrames", "CSV"]
Pkg.add(required_pkgs)
這兩個安裝的packages,其中CSV
主要是用來讀取、寫入表格資料檔案,而DataFrames
我則是用來對讀進來的表格資料進行各種處理及資料過濾。CSV
的使用方法我是直接透過官方提供的使用說明學習的,至於DataFrames
的使用,我則是透過一份人家整理好並在網路上分享的tutorial及Julia數據科學應用這本書的介紹學習的,中間在練習寫code的時候,當然還少不了參考#StackOverflow上面的討論啊 XD
建立一個DataFrame
要建立一個DataFrame有好幾種方式,比如說直接給定各欄位的內容:
using DataFrames
DataFrame(A=1:3, B=rand(3), C=randstring.([3,3,3]))
也可以先建立一個Dict
,再將這個Dict轉換成DataFrame:
x = Dict("A" => [1,2], "B" => [true, false], "C" => ['a', 'b'])
DataFrame(x)
這種方式還可以偷懶一點,直接用類似宣告一個Dict的方式建立DataFrame:
DataFrame(:A => [1,2], :B => [true, false], :C => ['a', 'b'])
不過這種方式跟前面那種相比,產生的DataFrame看起來會有點不同,主要是因為若我們餵一個Dict給DataFrame()
這個函數時,DataFrame()
會先對Dict裡頭的key
進行排序,才將它轉換成DataFrame。另外,我們還可以直接vector of vector
轉換成一個DataFrame,若要將一個vector
轉成一個DataFrame,則須先用permutedims()
將這個vector轉置才行。
獲得一個DataFrame的基本資訊
想知道這個表格資料有多大:
x = DataFrame(A = [1, 2], B = [1.0, missing], C = ["a", "b"])
size(x)
size(x, 1) # 取得row的數量,等同於 nrow(x)
size(x, 2) # 取得coloumn的數量,等同於ncol(x)及length(x)
想獲得每個欄位的名稱及每個欄位的資料型態:
names(x)
eltypes(x)
選取某個(些)欄位:
x[1], x[:A], x.A
讀取一個csv檔案
前面講的是怎麼產生一個DataFrame及怎麼操作一個DataFrame,但我們還得知道怎麼從檔案讀取資料才行。要讀取表格資料,我們可以用CSV.read()
來讀,其中header
指的是欄位名稱所在的列號,一旦指定了這個參數,真正的數據就會從下一列開始算。delim
則是指不同欄位之間的分隔符號,一般來說.csv
格式的檔案都是以逗號作為欄位的分隔符號:
using CSV
df = CSV.read("annotation.csv", header=1, delim=",")
今天就先到這,很多細節雖沒講,但都可在上面所附的連結中找到你可能需要的那些資訊。