csvtk: 命令行版極簡(jiǎn)dplyr

寫在前面

什么時(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
image
image

one more thing

文末還是要說回開發(fā)者遂铡。爪哥是一個(gè)非常勤奮的人们衙,可以看看他的 GitHub,嗯矾利,真綠。csvtk 最近一次 commit 是在 8 天前,seqkit 最近一次 commit 也是在 8 天前。

image

所以因篇,如果你在使用過程中有什么問題和需求笔横,不妨去給他提幾個(gè) issue吹缔,沒準(zhǔn)他一順手就實(shí)現(xiàn)了你的想法。


本文作者:思考問題的熊

版權(quán)聲明:本博客所有文章除特別聲明外茶没,均采用 知識(shí)共享署名-非商業(yè)性使用-禁止演繹 4.0 國(guó)際許可協(xié)議 (CC BY-NC-ND 4.0) 進(jìn)行許可。

加入靠譜熊基地喂急,和大家一起交流
添加我的微信
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末煮岁,一起剝皮案震驚了整個(gè)濱河市涣易,隨后出現(xiàn)的幾起案子新症,更是在濱河造成了極大的恐慌,老刑警劉巖荚醒,帶你破解...
    沈念sama閱讀 206,126評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件隆嗅,死亡現(xiàn)場(chǎng)離奇詭異胖喳,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)较剃,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,254評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門技健,熙熙樓的掌柜王于貴愁眉苦臉地迎上來雌贱,“玉大人,你說我怎么就攤上這事欣孤〉冀郑” “怎么了?”我有些...
    開封第一講書人閱讀 152,445評(píng)論 0 341
  • 文/不壞的土叔 我叫張陵款票,是天一觀的道長(zhǎng)泽论。 經(jīng)常有香客問我翼悴,道長(zhǎng),這世上最難降的妖魔是什么谍椅? 我笑而不...
    開封第一講書人閱讀 55,185評(píng)論 1 278
  • 正文 為了忘掉前任古话,我火速辦了婚禮陪踩,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘肩狂。我一直安慰自己傻谁,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,178評(píng)論 5 371
  • 文/花漫 我一把揭開白布荆秦。 她就那樣靜靜地躺著力图,像睡著了一般吃媒。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上刑桑,一...
    開封第一講書人閱讀 48,970評(píng)論 1 284
  • 那天募舟,我揣著相機(jī)與錄音,去河邊找鬼琢锋。 笑死,一個(gè)胖子當(dāng)著我的面吹牛钉嘹,可吹牛的內(nèi)容都是我干的鲸阻。 我是一名探鬼主播鸟悴,決...
    沈念sama閱讀 38,276評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼沛贪!你這毒婦竟也來了揍堰?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,927評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎蝙眶,沒想到半個(gè)月后幽纷,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,400評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡峰尝,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,883評(píng)論 2 323
  • 正文 我和宋清朗相戀三年武学,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了伦意。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 37,997評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡熏矿,死狀恐怖票编,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情乱豆,我是刑警寧澤吊趾,帶...
    沈念sama閱讀 33,646評(píng)論 4 322
  • 正文 年R本政府宣布瑟啃,位于F島的核電站蛹屿,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏坟瓢。R本人自食惡果不足惜犹撒,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,213評(píng)論 3 307
  • 文/蒙蒙 一识颊、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧祥款,春花似錦刃跛、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,204評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至脸狸,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間泥彤,已是汗流浹背卿啡。 一陣腳步聲響...
    開封第一講書人閱讀 31,423評(píng)論 1 260
  • 我被黑心中介騙來泰國(guó)打工颈娜, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人蛹磺。 一個(gè)月前我還...
    沈念sama閱讀 45,423評(píng)論 2 352
  • 正文 我出身青樓同仆,卻偏偏與公主長(zhǎng)得像俗批,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子岁忘,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,722評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容