csvtk——CSV_TSV文本处理万能工具

写在前面

能干什么? 学习任何一个工具或是文章中的一类炫酷图表时,我觉得首先需要能明白:这个工具/这类图表能干什么?这个工具/图的展示方式是最好的么,还有哪些不足之处。然后再是将这个工具/图表整合到自己的知识框架系统里面。等下次有类似需求的时候,就能够在个人的知识系统里面调用这类工具/图表去实现你的想法。

学习生物信息的分析流程过程中,需要处理各种格式的文件类型,如gtf/gff、vcf、bam等,其实这些文件本质上就是以tab作为分隔符的文本文件。我们利用各种生信工具(bedtools/vcftools/samtools)、grep/awk/sed,或者是自己写程序对其进行处理来实现自己的目的,而在这过程中速度和效率就是个很重要的因素。有时候自己在处理文件时花时间去写的一些脚本,用完就扔。偶然了解到csvtk这个工具,发现其实以前写的许多脚本在这个工具中一行命令就能解决,是个效率提升的好轮子,决定好好学习一下csvtk的使用。

csvtk是shenwei爪哥开发的又一大利器。据说是shenwei在投稿seqkit文章时顺便写的工具。(fasta/fq文件处理万能工具——Seqkit学习记录)嗯,我也希望能在以后科研空闲时开发一些为人民服务的好轮子。话说回来了,能用csvtk这类好轮子,更要能自己去造轮子。在利用工具去快速实现一些目标的时候,也需要想一想,如果是自己利用不同的语言去写程序实现,思路是什么?时常写一写也可以保持自己的coding的能力。

本教程根据官方说明文档(https://bioinf.shenwei.me/csvtk/usage/)做的学习,推荐可以根据官方Usage中的各种例子去多多练习,示例文件地址(https://github.com/shenwei356/csvtk/tree/master/testdata)。

csvtk使用前注意

  • csvtk处理时默认会自动保留表头。认为csv文件的第一行为header信息,如果没有header,需指定参数-H
  • 默认是处理以,作为分割的csv文件,处理\t tab分割的tsv文件,指定参数-t
  • csv文件默认每行(rows)都有相同的列数(columns),-I/--ignore-illegal-row跳过这些错误行
  • csv文件每列(columns)的名字不重复。
  • 默认会忽略#,指定header的符号-C
  • 若每列中存在双引号"",指定参数-1

文件基本信息(Information)

1. headers 只显示表头
2. dim 显示csv文件的每行每列数目
3. summary 可根据分组信息(group_by)对每列(columns)进行数学统计

类似于R中dplyr包中的summary函数,其中对数字进行的数学统计包括countn(统计数字有多少), min, max, sum, mean, stdev, variance, median, q1, q2, q3, entropy, prod,对字符文本的包括:count(计数), first, last, rand(随机取值), uniq(去重), collapse(转为以;的一行信息), countunique(uniq之后计数有多少)。基本用法:csvtk summary -f 2:sum

  • -f 2/column_name2:sum/mean... 指定第几列进行统计,可进行多列统计。
  • -i 忽略列中的非数字缺失值NA
  • -g 类似于dplyr中的group_by,根据某列进行分组统计。
  • -n 2 保留几位小数
  • -S 11 设置随机种子
  • -s ; 设置collapse的为一列时的分割符号
## 第四列 总和
cat digitals2.csv  | csvtk summary -f f4:sum

## 多列进行计算,忽略NA
cat digitals2.csv | csvtk summary -f f4:sum,f5:sum -i
cat digitals2.csv | csvtk summary -f 4:sum,5:sum -i

## 分组统计
cat digitals2.csv | csvtk summary -i -f f4:sum,f5:sum -g f1,f2 | csvtk pretty
## 去第一行header
cat digitals2.csv|csvtk summary -f 4:sum -f 5:sum -i -g 1,2|sed 1d

## 分组统计多个信息:
cat digitals2.csv | csvtk summary -i -g f1 -f f4:countn,f4:mean,f4:stdev,f4:q1,f4:q2,f4:mean,f4:q3,f4:min,f4:max
cat digitals2.csv | csvtk summary -i -g f1 -f f4:collapse,f4:max|csvtk pretty


格式转变

1. pretty 方便阅读的展示方式。
  • -r 靠右对齐
  • -s 指定分割符号 " | "
2. transpose 对数据进行转置,行列转换
3. space2tab 以空格分割的转为tab分割的。
4. csv2md csv/tsv转变为markdown格式。
5. csv2json csv转变为json格式
6. xlsx2csv 对EXCEL的xlsx文件转换为csv文件
  • -a 显示所有的附表sheets
  • -i 2 对第几个附表进行操作。 csvtk xlsx2csv accounts.xlsx -i 3
  • -n 根据附表的名字进行提取。

集合操作 set operation

1. head 显示前n行,包括表头header
2. concat concatenate。对多个tsv/csv表根据表头columns对行rows合并。

只保留第一个表的header,类似于dplyr中的left_join()

  • -i 每个表的表头column_name忽略大小写。
  • -u NA 未匹配到的空的数据以任意"NA"表示
  • -k 保留未匹配到合并的数据,以-u字符表示
## 合并col_names相同的表
csvtk concat names.csv names.reorder.csv |csvtk pretty

## 忽略大小写,保留空的行,以"NA"表示
csvtk concat names.csv names.with-unmatched-colname.csv -i -u NA | csvtk pretty

3. sample 随机取一定比例的行数
  • -p 0.1 取的比例
  • -s 10 设置随机种子,默认11。seq 100 | csvtk sample -H -p 0.1 -s 1
  • -n 显示随机的行rownames名,
4. cut 取指定列columns,

类似于dplyr中的select,或者linux中进阶的cut

  • -f 1,2 || colA,colB 根据数字 or col_name来选指定列。可反选 -f -1,-2
  • -i 忽略col_name中的大小写
  • -F 允许部分正则匹配 *name
## 根据表头column名进行挑选
cat names.csv |csvtk cut -f first_name,username

## 选第2~4列
cat names.csv | csvtk cut -f 2-4

## 反选,即除了第一,二列
cat names.csv | csvtk cut -f -1,-2
cat names.csv | csvtk cut -f -username

## 允许部分正则匹配的 * 
cat names.csv | csvtk cut -f "*_name"

5. uniq 对指定多列自动排序去重复

等同于Linux中的sort | uniq

6. freq对指定列去重复,顺便计数排序。

等同于Linux中的sort |uniq -c-f,-F,-icut子命令

  • -n 根据计数从小到大排序
  • -k 根据名字key排序
  • -r 反过来
### 对第二列排序,并按照frequency的数值从大到小排列
cat names.csv |csvtk freq -f 2 -nr

7. inter 多个文件之间的交集。

-f, -F, -i等同于cut子命令。

8. grep 对指定列进行key的正则匹配提取

类似于dplyr中的filter()函数对某column的字符串chr进行匹配操作。

  • -f 指定列的col_name,1-3列
  • -p pattern 搜索提取的pattern
  • -P 提取pattern的文件,多个pattern进行提取
  • -i 忽略大小写
  • -v 反向匹配。
  • -r 支持正则匹配
  • -n 显示提取的行号。
cat names.csv | cavtk grep -f 1 -ir -p rob |csvtk pretty 

## 对names.csv的first_name随机取几个名子作为file,再对names.csv文件根据文件进行提取
cat names.csv |csvtk cut -f 3 |sed 1d|csvtk sample -p 0.5 -H| csvtk grep -f 3 -ir -P - names.csv |csvtk pretty

9. filter 利用数学公式,对指定列进行数值的过滤提取。

类似于dplyr中的filter()函数对数值的处理方式。

  • -f 1,2>0 对指定列进行数值的过滤
  • --any 多列进行过滤,满足任意一列条件皆保留。
  • -F, -n
## 第1~3列任意列大于0即保留。
cat  digitals.tsv | csvtk -t -H filter -f "1-3>0" --any
10. filter2类似于awk的数据过滤方式。

支持awk中的数值/表达式,按指定多列的数值进行过滤。

## id列大于3
cat names.csv | csvtk filter2 -f '$id > 3'

## id列大于3 或 username列 为 "ken"
cat names.csv | csvtk filter2 -f ' $id > 3 || $username == "ken" '

## other arithmatic expressions
cat digitals.tsv | csvtk filter2 -H -t -f '$1 > 2 && $2 % 2 == 0'

cat digitals.tsv | csvtk filter2 -H -t -f '$2 <= $3 || ( $1 / $2 > 0.5 )'
11. join 对多个文件按指定列进行合并。

类似concat?或者dplyr中的left_join()

  • -f 按第一个文件指定列进行合并,文件中的col_name名不用完全相同。若指定匹配的列 以-f "colA_1;colB_2"表示。
  • -k -fill NA 保留未匹配的,以NA表示。
csvtk join {1,2,3}.csv -f name -k
csvtk join {3,1,2}.csv -f name -k
12. split 根据指定column的value进行分割文件。
  • -f 1~3 || columnA 指定列以factor方式分割文件
  • -o 对分割的文件指定输出文件夹
### 根据first_name, last_name分割文件
csvtk split names.csv -f first_name,last_name

### 分割输出到result文件夹
seq 100 | csvtk split -H -o result

13. splitxlsx 类似于split,对xlsx表内按照列column进行分割出多个文件。

文件的内容编辑相关

1. add-header 添加列的名字。-n a,b,c
2. del-header 删除列的名字
3. rename 对column名修改
  • -f 1,2 指定列进行改名
  • -n a,b 对指定列进行改名。
## 对A,B列进行改名
cat phones.csv | csvtk rename -f A,B -n a,b | csvtk pretty

4. rename2 正则匹配来对指定多列名进行修改。

类似于dplyr中的rename_all() iris %>% rename_all(tolower) %>% rename_all(~str_replace_all(., "\\.", "_"))

  • -f 指定列进行修改。
  • -p 正则匹配的字符。
  • -r 修改过后的字符。'${1}'的使用 '{nr}', '{nk}'
  • -k 按照指定key-value的文件进行改名。
  • -K 保留-k中未匹配的到的列名
### 对所有的列名进行修改,添加prefix_${1}_suffix
cat phones.csv | csvtk rename2 -F -f "*" -p '(.*)' -r 'prefix_${1}_suffix'

### 根据barcodes的key-value对应关系 来 对tables.tsv进行改列名。
csvtk cut -t barcodes.tsv -f 2,1 | csvtk rename2 -t -F -f "*" -k - -p '(.+)' -r '{kv}' -K tables.tsv

### 改列名利用增长的1~n
echo "a,b,c,d" | csvtk rename2 -f 2-4 -p '(\w+)' -r 'seq_{nr}' --start-num 2

5. replace 根据正则匹配对指定多列进行替换编辑

类似于rename的一些操作。

  • -F -f "*"指定所有列
  • -p pattern 正则匹配的pattern
  • -r 替换的string,支持${1}自动捕获,{nr},{nk}
  • -k 可根据key-value的文件进行批量替换
  • -K -k中保留未匹配的文字。
###删除文件中的汉字
csvtk replace -F -f "*_name" -p "\p{Han}+" -r ""

### 根据key-value的文件进行匹配替换,时刻记住处理tsv文件加参数 -t

csvtk replace -t -f 2 -p 'ID(\d+)' -r '{kv}' -K -k alias.txt data.tsv

6. mutate 根据正则匹配创建新的一列

类似于dplyr中的mutate()

  • -f 指定列,-iignore case
  • -p pattern 对列的内容 利用正则匹配捕获
  • -n 添加新列的新的名字
### 复制新列
csvtk mutate -f id -n newname

### 对username列 的第一个字母进行匹配,以新列展示
cat phones.csv | csvtk mutate -f 1 -p '^(\w)' -n 'first_name' | csvtk pretty

7. mutate2 类似于awk的方式创建新的列
  • -e awk类似的表达式, 连接,数值的相加等~
  • -L 2 数值计算时,默认保留2位小数。
  • -s 将数值num当字符chr
### 添加新列
cat digitals.tsv |csvtk mutate2 -t -H -e ' "a" '

### 添加新列,自建变量
var=123
cat digitals.tsv |csvtk mutate2 -t -H -e "$var"

### 两列进行连接
cat names.csv | csvtk mutate2 -n full_name -e ' $first_name + " " + $last_name'

### 数值的相加
cat digitals.tsv | csvtk mutate2 -t -H -L 0 -e ' $1 + $2 '

### 相比较
cat digitals.tsv | csvtk mutate2 -t -H -L 0 -e ' $1 >5 ? "big":"small" '
8. gather 表格的整理

类似于tidyr中的gather()函数,对相同的列数据进行整理。

cat names.csv | csvtk gather -f -1 -k name -v value 


排序

sort 对指定列 排序
  • -i 忽略大小写
  • -k 对指定列排序 -k 1:N/n/u/r
### 对指定列排序
cat names.csv | csvtk sort -k first_name | csvtk pretty

### 对指定列倒序
cat names.csv | csvtk sort -k first_name:r | csvtk pretty

### 对指定列按数值排序,倒序
cat names.csv | csvtk sort -k first_name:nr | csvtk pretty

### 按自然顺序排序N
echo "X,Y,1,10,2,M,11,1_c,Un_g,1_g" | csvtk transpose | csvtk sort -H -k 1:N

### 按多列进行排序
cat names.csv | csvtk sort -k first_name -k id:n

plot 画一些通常的直方图,箱线图,散点图。
  • csvtk plot hist
  • csvtk plot box
  • csvtk plot line

足够强大的工具!推荐学习使用!

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,560评论 4 361
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,104评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,297评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,869评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,275评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,563评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,833评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,543评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,245评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,512评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,011评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,359评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,006评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,062评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,825评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,590评论 2 273
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,501评论 2 268

推荐阅读更多精彩内容