寫在前面
什么時(shí)候?qū)?csvtk 呀,csvtk 也借鑒了些 datamash 的東西严就。
之前寫 datamash 的使用教程冲九,收到了一位讀者的私信策泣,內(nèi)容如上馅扣。
話說這位讀者不是別人,正是大名鼎鼎 seqkit 和 csvtk 的開發(fā)者 shenwei356 (github ID)着降,江湖人稱「爪哥」差油。我從來沒有問過他為什么 ID 有個(gè)數(shù)字后綴「356」,我私以為是一年 365 天里有 356 天他都在寫程序任洞,剩下的幾天過年放假蓄喇。說到爪哥,如果你看到這篇文章之前不知道他我不怪你交掏,但是今天以后希望他可以每天都和你在一起妆偏。
爪哥用兩個(gè)工具就讓自己在生物信息領(lǐng)域有了一席之地。其中 seqkit 是用來處理 fasta/q 文本的工具盅弛,這篇文章要寫的 csvtk 是處理 c/tsv 文本的工具钱骂。如果你感覺我的說法夸張了,不妨想想每天接觸到的各種文件挪鹏,無論是 gff 還是 bed 還是 sam 甚至是 vcf见秽,其本質(zhì)都是 tsv 格式,再加上 seqkit 針對(duì)的 fasta 和 fastq讨盒。如果你能熟練使用這兩個(gè)工具解取,今后的每一天就都會(huì)感受到爪哥無微不至的關(guān)懷。我經(jīng)常在敲完一行命令后會(huì)在心里大喊一聲「爪哥NB」返顺。
csvtk 特點(diǎn)
熟悉 Linux 的人談到命令行的文本處理禀苦,定會(huì)奉上文本處理「三劍客」:awk蔓肯,sed,grep振乏。csvtk 并不想搶他們的風(fēng)頭蔗包,而是可以無痛的整合到各種處理流程中。它憑借自己的特點(diǎn)慧邮,讓命令行里的文本處理更容易。
csvtk 的特點(diǎn)之一是對(duì) header 的識(shí)別和處理,它可以讓你省去很多原本在使用 awk 等命令時(shí)針對(duì) header 行的代碼吨娜。既然考慮到了 header宦赠,特點(diǎn)之二就是支持通過列名來進(jìn)行列的選擇,這里的選擇還包括反選和模糊選擇勾扭。除此之外,之所以說便于和其他流程的整合桅滋,還因?yàn)樗梢灾苯犹幚順?biāo)準(zhǔn)輸入和壓縮文本身辨,同時(shí)這個(gè)軟件本身不需要編譯也沒有任何其它依賴,非常容易安裝号俐,conda 可以直接搞定定庵。
csvtk 本身支持多線程以及若干子命令蔬浙,用起來會(huì)發(fā)現(xiàn)通常其速度和效率比在 python 和 R 中輸入很多行代碼都要高畴博。如果這些依舊不能打動(dòng)你绎晃,csvtk 還有一個(gè)神奇的功能:直接用一行代碼在命令行里畫圖。真 6袁余。
csvtk 介紹
csvtk 有三十多個(gè)子命令,基本上可以理解為是命令行版極簡(jiǎn) dplyr 加若干 linux 命令的增強(qiáng)整合。子命令按照類別和功能分類噪漾,可以分為如下幾類欣硼,其中結(jié)尾帶有+
的子命令是我常用的和值得尤其關(guān)注的恶阴。
文本信息類
-
headers
打印首行(列名) -
dim
查看文件的行列數(shù) 诈胜,和 R 中的dim
類似+
-
summary
對(duì)所選列進(jìn)行簡(jiǎn)單的描述性統(tǒng)計(jì),如果是統(tǒng)計(jì)內(nèi)容是數(shù)字昵仅,則類似于 R 中的summary()
摔笤,同時(shí)支持分組統(tǒng)計(jì)。如果統(tǒng)計(jì)內(nèi)容是文本寞冯,支持類似于datamash
的多內(nèi)容統(tǒng)計(jì)吮龄。+
格式轉(zhuǎn)化類
-
pretty
可以讓 csv 變成漂亮的對(duì)齊易讀表格+
-
transpose
類似于 R 中的t()
對(duì)數(shù)據(jù)進(jìn)行轉(zhuǎn)置 -
csv2json
則可以讓數(shù)據(jù)轉(zhuǎn)換為 json 格式 -
csv2md
則是炫酷的直接變成 markdown 支持的表格+
集合操作類
這一類命令是操作的重點(diǎn)母债,有很多子命令毡们,其中部分類似于 unix 中對(duì)應(yīng)的命令但又有所區(qū)別衙熔。
-
head
查看文件開始若干行 -
concat
合并文件红氯,類似于cat
但是可以按照列名進(jìn)行匹配合并 -
sample
按照比例對(duì)文本進(jìn)行提取 -
cut
按照列選擇喇嘱,支持列數(shù)和列名塞栅,支持反選和模糊選擇+
-
uniq
無需排序進(jìn)行去重+
-
freq
所選字段評(píng)率統(tǒng)計(jì) -
inter
多個(gè)文件取交集 -
grep
類似于 lunix 的 grep,支持正則和反選等操作+
-
filter
按照數(shù)學(xué)表達(dá)式篩選悔据,支持多列判斷科汗,精簡(jiǎn)版 -
filter2
按照數(shù)學(xué)表達(dá)式篩選头滔,約等于 lunix 中的 awk,復(fù)雜版+
-
join
按照字段合并多個(gè)文件兴猩,類似于 linux 的 join -
split
按照某列值拆分文件早歇,也就是分組保存為多個(gè)文件 -
collapse
按照所選字段的 key 合并其它字段+
文本編輯類
如果你熟悉 R 中的 dplyr,這類型的子命令中有不少都會(huì)讓你感覺熟悉。
-
add-header
增加列名 -
del-header
刪除列名 -
rename
對(duì)列重命名 -
rename2
支持正則表達(dá)式的列重命名 -
replace
通過正則表達(dá)式替換所選列對(duì)應(yīng)的內(nèi)容借尿,支持捕獲變量,內(nèi)置特殊替換符號(hào)+
-
mutate
對(duì)某一列進(jìn)行正則表達(dá)處理增加新的一列 -
mutate2
對(duì)多列進(jìn)行 awk 類似的字符和數(shù)學(xué)表達(dá)式處理,增加新列+
-
gather
類似于 dplyr 中的gather()
函數(shù)帚桩,數(shù)據(jù)「由寬變長(zhǎng)」 -
sort
支持按照一列或者多列排序账嚎,且支持自定義順序排序
畫圖
借助 gonum 中的 plot 包郭蕉,csvtk 還可以直接畫一些基本的統(tǒng)計(jì)圖召锈,這功能其實(shí)已經(jīng)超越 dplyr 向著 ggplot2 挺進(jìn)了涨岁。畫圖相關(guān)命令可以根據(jù)文件后綴自動(dòng)確定輸出類型梢薪。
plot 支持 boxplot, histogram, line 和 scatter 四種圖秉撇,圖的主要元素都可以設(shè)置琐馆,支持的輸出格式包括 eps/pdf/svg/tiff/jpg/png谁撼,對(duì)應(yīng)如下三個(gè)命令:
csvtk plot hist
csvtk plot box
csvtk plot line
csvtk 示例
因?yàn)槠脑蚶鞯@里僅展示幾個(gè)使用示例墨榄,更多更詳細(xì)的內(nèi)容可以直接參考爪哥寫的使用文檔袄秩。另外本文使用的數(shù)據(jù)也來自官方測(cè)試數(shù)據(jù)之剧。
描述統(tǒng)計(jì)量
csvtk 的 summary
命令有兩個(gè)亮點(diǎn)背稼,第一是支持對(duì)文本和數(shù)值的多種分組統(tǒng)計(jì)词疼;第二個(gè)是可以過濾對(duì)應(yīng)字段的非數(shù)值內(nèi)容(比如N/A
)帘腹。
$ cat digitals2.csv
f1,f2,f3,f4,f5
foo,bar,xyz,1,0
foo,bar2,xyz,1.5,-1
foo,bar2,xyz,3,2
foo,bar,xyz,5,3
foo,bar2,xyz,N/A,4
針對(duì)上述數(shù)據(jù)舵盈,按照第一列和第二列進(jìn)行分組筒愚,同時(shí)計(jì)算第四列和第五列的和扯再,排除非數(shù)值內(nèi)容,以易讀方式輸出結(jié)果。命令如下:
$ cat digitals2.csv | \
csvtk summary -i -f f4:sum,f5:sum -g f1,f2 | \
csvtk pretty
f1 f2 f4:sum f5:sum
bar xyz 7.00 106.00
bar xyz2 4.00 4.00
foo bar 6.00 3.00
foo bar2 4.50 5.00
一鍵變漂亮
上面已經(jīng)用到的pretty
命令可以讓輸出的結(jié)果更加易讀鳄袍。
$ cat names.csv
id,first_name,last_name,username
11,Rob,Pike,rob
2,Ken,Thompson,ken
4,Robert,Griesemer,gri
1,Robert,Thompson,abc
$ cat names.csv |csvtk pretty
id first_name last_name username
11 Rob Pike rob
2 Ken Thompson ken
4 Robert Griesemer gri
1 Robert Thompson abc
$ cat names.csv |csvtk pretty -r
id first_name last_name username
11 Rob Pike rob
2 Ken Thompson ken
4 Robert Griesemer gri
1 Robert Thompson abc
無需排序快速去重
之前曾經(jīng)討論一個(gè)大文本去重的問題拗小,從當(dāng)時(shí)的結(jié)果來看搅幅,對(duì)于大文本在 linux 中排序是去重的主要限速步驟呼胚。但是在 csvtk 中沪编,可以不通過排序而直接進(jìn)行去重漾抬。針對(duì)當(dāng)時(shí)的問題常遂,對(duì)于一個(gè) 3,741,430 行的文本,先排序再去重需要 30s 左右的時(shí)間漠另,而使用 csvtk uniq 僅需要兩三秒。
time awk 'OFS="\t" { if($1>$2){print $2,$1,$3} else {print} }' howtouniq.txt \
| csvtk uniq -H -t -f 1,2 > howtouniq.txt.awk-csvtk
#real 0m2.674s
#user 0m5.660s
#sys 0m0.482s
復(fù)雜條件篩選數(shù)據(jù)
csvtk 中的 filter2
支持使用復(fù)雜條件篩選數(shù)據(jù)算墨,類似于 awk报咳。首先支持 + - / * & | ^ ** %
等運(yùn)算岩臣,也支持> >= < <= == != =~ !~
婿脸,同時(shí)還可以使用|| &&
對(duì)多個(gè)條件進(jìn)行組合。例如:
$ cat names.csv
id,first_name,last_name,username
11,"Rob","Pike",rob
2,Ken,Thompson,ken
4,"Robert","Griesemer","gri"
1,"Robert","Thompson","abc"
NA,"Robert","Abel","123"
$ cat names.csv | csvtk filter2 -f '$id > 3 || $username=="ken"'
id,first_name,last_name,username
11,Rob,Pike,rob
2,Ken,Thompson,ken
4,Robert,Griesemer,gri
快速添加新列
使用mutate2
可以按照復(fù)雜運(yùn)算快速添加新的內(nèi)容幻件,支持的操作和filter2
一致。
比如拼接字符串:
$ cat names.csv \
| csvtk mutate2 -n full_name -e ' $first_name + " " + $last_name ' \
| csvtk pretty
id first_name last_name username full_name
11 Rob Pike rob Rob Pike
2 Ken Thompson ken Ken Thompson
4 Robert Griesemer gri Robert Griesemer
1 Robert Thompson abc Robert Thompson
NA Robert Abel 123 Robert Abel
甚至還可以通過三元運(yùn)算符進(jìn)行判斷填空:
cat digitals.tsv | csvtk mutate2 -t -H -e '$1 > 5 ? "big" : "small" '
4 5 6 small
1 2 3 small
7 8 0 big
8 1,000 4 big
單行命令快速出圖
在測(cè)試數(shù)據(jù)中麸塞,有一組數(shù)據(jù)包含不同組別的序列長(zhǎng)度和 GC 含量,可以通過plot hist
繪制長(zhǎng)度的直方圖章贞,通過plot box
繪制每組的 GC 含量箱線圖两踏。
$ zcat grouped_data.tsv.gz | head -n 5 | csvtk -t pretty
Group Length GC Content
Group A 97 57.73
Group A 95 49.47
Group A 97 49.48
Group A 100 51.00
csvtk -t plot hist grouped_data.tsv.gz -f 2 --title Histogram -o histogram.png
csvtk -t plot box grouped_data.tsv.gz -g "Group" -f "GC Content" --width 3 --title "Box plot" > boxplot.png
one more thing
文末還是要說回開發(fā)者遂铡。爪哥是一個(gè)非常勤奮的人们衙,可以看看他的 GitHub,嗯矾利,真綠。csvtk 最近一次 commit 是在 8 天前,seqkit 最近一次 commit 也是在 8 天前。
所以因篇,如果你在使用過程中有什么問題和需求笔横,不妨去給他提幾個(gè) issue吹缔,沒準(zhǔn)他一順手就實(shí)現(xiàn)了你的想法。
本文作者:思考問題的熊
版權(quán)聲明:本博客所有文章除特別聲明外茶没,均采用 知識(shí)共享署名-非商業(yè)性使用-禁止演繹 4.0 國(guó)際許可協(xié)議 (CC BY-NC-ND 4.0) 進(jìn)行許可。