tidyverse

1 介绍

集合了dplyr,tidyr,ggplot2,stringr等软件的一款工具包合集,可以轻松的实现数据规整(dplyr),数据清洗(tidyr),字符串操作(stringr),以及后续作图(ggplot2),这些操作都可以被magrittr的管道符%>%连接起来,管道允许将前一个命令的输出用作另一个命令的输入,而不是使用嵌套函数,使整个命令看起来更加整洁。tidyverse还引进了一种新的矩阵格式tibble用于取代data.frame,对比data.frame有几点不同:1)tibble更加懒惰,不会将string类型的数据转换成factor;2)tibble只显示数据集的前十行;3)tibble挑选子集有$和[[两种方式;在管道中使用可以用.占位符;4)在tibble中并不会保留行名,所以在转换中需要先使用rownames_to_column()column_to_rownames()转换行名。

使用公共数据airway作为例子数据
library(airway)
data('airway')
airway
##class: RangedSummarizedExperiment 
##dim: 64102 8 
##metadata(1): ''
##assays(1): counts
##rownames(64102): ENSG00000000003 ENSG00000000005 ... LRG_98 LRG_99
##rowData names(0):
##colnames(8): SRR1039508 SRR1039509 ... SRR1039520 SRR1039521
##colData names(9): SampleName cell ... Sample BioSample

##一共有2组8个样本,64102行的RangedSummarizedExperiment对象,建议了解一下RangedSummarizedExperiment的使用
##在单细胞分析中常用的SingleCellExperiment与这个也十分类似。

#提取表达矩阵,matrix格式
rt <- assay(airway)
rt <- as.data.frame(rt)

tmp = rt[1:100,]
tmp <-tmp %>% rownames_to_column() %>% as.tibble()
tmp
# A tibble: 100 x 9
   rowname         SRR1039508 SRR1039509 SRR1039512 SRR1039513 SRR1039516 SRR1039517 SRR1039520 SRR1039521
   <chr>                <int>      <int>      <int>      <int>      <int>      <int>      <int>      <int>
 1 ENSG00000000003        679        448        873        408       1138       1047        770        572
 2 ENSG00000000005          0          0          0          0          0          0          0          0
 3 ENSG00000000419        467        515        621        365        587        799        417        508
 4 ENSG00000000457        260        211        263        164        245        331        233        229
 5 ENSG00000000460         60         55         40         35         78         63         76         60
 6 ENSG00000000938          0          0          2          0          1          0          0          0
 7 ENSG00000000971       3251       3679       6177       4252       6721      11027       5176       7995
 8 ENSG00000001036       1433       1062       1733        881       1424       1439       1359       1109
 9 ENSG00000001084        519        380        595        493        820        714        696        704
10 ENSG00000001167        394        236        464        175        658        584        360        269
# ... with 90 more rows

dplyr

在R中进行数据处理时,免不了对矩阵进行操作,而dplyr则是一个有力的工具用来对矩阵进行操作,其中包含的select(),arrange(),filter(),mutate(),rename(),_join(),pull()等函数几乎包括了所有矩阵处理操作,并且这些操作还可以被%>%连接起来一起用于矩阵的处理。

select()提取操作,类似基础函数中的rt$提取操作或者rt[]坐标提取


tmp %>% select(SRR1039512,SRR1039516) %>% head()

                SRR1039512 SRR1039516
ENSG00000000003        873       1138
ENSG00000000005          0          0
ENSG00000000419        621        587
ENSG00000000457        263        245
ENSG00000000460         40         78
ENSG00000000938          2          1
##还可以使用-()实现负提取
tmp %>% select(-c(SRR1039512,SRR1039516)) %>% head()

                SRR1039508 SRR1039509 SRR1039513 SRR1039517 SRR1039520 SRR1039521
ENSG00000000003        679        448        408       1047        770        572
ENSG00000000005          0          0          0          0          0          0
ENSG00000000419        467        515        365        799        417        508
ENSG00000000457        260        211        164        331        233        229
ENSG00000000460         60         55         35         63         76         60
ENSG00000000938          0          0          0          0          0          0

arrange()实现排序操作,默认升序,可以使用符号或者desc进行降序操作,类似R中内置的order函数。

#select负筛选SRR1039512,SRR1039516后对SRR1039512进行降序排列
tmp %>% select(-c(SRR1039512,SRR1039516)) %>% arrange(desc(SRR1039512)) %>% head()

# A tibble: 6 x 7
  rowname         SRR1039508 SRR1039509 SRR1039513 SRR1039517 SRR1039520 SRR1039521
  <chr>                <int>      <int>      <int>      <int>      <int>      <int>
1 ENSG00000002586       7507       7203       6214      12863       6834       7225
2 ENSG00000002834       6314       6364       5809      11970       5766       7825
3 ENSG00000003436       4373       4183       3230       4981       3452       3342
4 ENSG00000004399       4077       4260       1649       5992       2718       2809
5 ENSG00000004776       3473       3078       1621       2254       3571       3153
6 ENSG00000000971       3251       3679       4252      11027       5176       7995

filter()可以按条件筛选,还支持多个条件筛选,判断符号还有==,>=,>,&,|,xor(),is.na()等,多个条件可以使用逗号分隔。

#筛选SRR1039520样本表达量大于3000以及SRR1039512样本中表达量小于9000的基因
tmp %>% filter(SRR1039520 > 3000 & SRR1039512 < 9000)

# A tibble: 4 x 9
  rowname         SRR1039508 SRR1039509 SRR1039512 SRR1039513 SRR1039516 SRR1039517 SRR1039520 SRR1039521
  <chr>                <int>      <int>      <int>      <int>      <int>      <int>      <int>      <int>
1 ENSG00000000971       3251       3679       6177       4252       6721      11027       5176       7995
2 ENSG00000002834       6314       6364       7831       5809       6677      11970       5766       7825
3 ENSG00000003436       4373       4183       5794       3230       7344       4981       3452       3342
4 ENSG00000004776       3473       3078       2775       1621       2084       2254       3571       3153

mutate()可以用来添加列并进行命名,同时mutate()还支持将新添加的列作为变量传递以进行后续操作。类似于transform()函数。将SRR1039509列取log操作后创建新一列并命名为log2SRR1039509。

tmp %>% mutate(log2SRR1039509=log2(SRR1039509+1))

# A tibble: 100 x 10
   rowname         SRR1039508 SRR1039509 SRR1039512 SRR1039513 SRR1039516 SRR1039517 SRR1039520 SRR1039521 log2SRR1039509
   <chr>                <int>      <int>      <int>      <int>      <int>      <int>      <int>      <int>          <dbl>
 1 ENSG00000000003        679        448        873        408       1138       1047        770        572           8.81
 2 ENSG00000000005          0          0          0          0          0          0          0          0           0   
 3 ENSG00000000419        467        515        621        365        587        799        417        508           9.01
 4 ENSG00000000457        260        211        263        164        245        331        233        229           7.73
 5 ENSG00000000460         60         55         40         35         78         63         76         60           5.81
 6 ENSG00000000938          0          0          2          0          1          0          0          0           0   
 7 ENSG00000000971       3251       3679       6177       4252       6721      11027       5176       7995          11.8 
 8 ENSG00000001036       1433       1062       1733        881       1424       1439       1359       1109          10.1 
 9 ENSG00000001084        519        380        595        493        820        714        696        704           8.57
10 ENSG00000001167        394        236        464        175        658        584        360        269           7.89
# ... with 90 more rows

tmp %>% transmute(log2SRR1039509=log2(SRR1039509+1))
##transmute只保留新创建的列。
# A tibble: 100 x 1
   log2SRR1039509
            <dbl>
 1           8.81
 2           0   
 3           9.01
 4           7.73
 5           5.81
 6           0   
 7          11.8 
 8          10.1 
 9           8.57
10           7.89
# ... with 90 more rows

summarize()聚合汇总操作,对数据框调用函数进行操作之后返回结果,常用函数包括mean,max,min等,常用于分组以后的处理。

tmp %>% summarise(a=mean(SRR1039509))
# A tibble: 1 x 1
      a
  <dbl>
1  720.

##骚操作,对重复的基因名取最大值/平均值
tmp %>% group_by(rowname) %>% summarise_all(mean)
##summarise_all同时对所有组进行摘要,并不需要重新命名
  • rename(new_name= old_name)对列进行重命名
  • pull()挑选一列内容展示为向量
  • group_by()分组操作
  • distinct()去除一列中重复的项,支持使用distinct_all()对所有列进行操作
  • sample_n()sample_frac()抽样函数,随机抽取指定行,sample_n指定行数,而sample_frac表示百分比的行数,同时,sample_frac支持指定replace == T 表示bootstrap抽样,通过weight指定权重参数。
_join()函数

连接操作,可以针对两个数据框中存在的变量或变量集将一对数据框连接在一起。其中包含inner_join()(只有两个数据集都中存在的行将连接在一起),left_join()(保留第一个数据框中的所有行),right_join()(保留第二个数据框中的所有行),full_join()(保留两个数据集中的所有行)。

tidyr

tidyr主要提供了一个类似Excel中数据透视表(pivot table)的功能;gatherspread函数将数据在长格式和宽格式之间相互转化,应用在比如稀疏矩阵和稠密矩阵之间的转化,当我们使用ggplot2进行可视化的时候,gather是少不了的。

另外tidyr还有uniteseparate根据符号进行列合并或者分隔,类似于stringr中的功能。

tmp %>%  gather(key=key,value=value,-rowname)

# A tibble: 800 x 3
   rowname         key        value
   <chr>           <chr>      <int>
 1 ENSG00000000003 SRR1039508   679
 2 ENSG00000000005 SRR1039508     0
 3 ENSG00000000419 SRR1039508   467
 4 ENSG00000000457 SRR1039508   260
 5 ENSG00000000460 SRR1039508    60
 6 ENSG00000000938 SRR1039508     0
 7 ENSG00000000971 SRR1039508  3251
 8 ENSG00000001036 SRR1039508  1433
 9 ENSG00000001084 SRR1039508   519
10 ENSG00000001167 SRR1039508   394
# ... with 790 more rows

##gather时首先指定key列以及value列,key参数提供原数据框列名聚成的新列的名称,使用value参数提供所有值聚合成的的列##的名称,负号指定不变的列,这里指定rowname列不变。

spread()函数与gather()函数相反。key列的类别将成为单独的新列,value列中的值将根据关联的key列进行拆分。

tmp %>%  gather(key,value,-rowname) %>% spread(key,value)

# A tibble: 100 x 9
   rowname         SRR1039508 SRR1039509 SRR1039512 SRR1039513 SRR1039516 SRR1039517 SRR1039520 SRR1039521
   <chr>                <int>      <int>      <int>      <int>      <int>      <int>      <int>      <int>
 1 ENSG00000000003        679        448        873        408       1138       1047        770        572
 2 ENSG00000000005          0          0          0          0          0          0          0          0
 3 ENSG00000000419        467        515        621        365        587        799        417        508
 4 ENSG00000000457        260        211        263        164        245        331        233        229
 5 ENSG00000000460         60         55         40         35         78         63         76         60
 6 ENSG00000000938          0          0          2          0          1          0          0          0
 7 ENSG00000000971       3251       3679       6177       4252       6721      11027       5176       7995
 8 ENSG00000001036       1433       1062       1733        881       1424       1439       1359       1109
 9 ENSG00000001084        519        380        595        493        820        714        696        704
10 ENSG00000001167        394        236        464        175        658        584        360        269
# ... with 90 more rows
  • separate()支持根据特定符号分隔字符串,类似于str_split()
  • unite()按照指定符号将列合并
#常见的去除ensembl id版本号的操作
tmp<- tmp %>% 
  tidyr::separate(gene_id,into = c("gene_id","drop"),sep="\\.") %>% 
  dplyr::select(-drop) 

#将基因名,ensembl id以及基因类型根据" | "进行合并,进行去重操作之后在分开
tmp<- tmp%>% 
  tidyr::unite(gene_id,gene_name,gene_id,gene_type,sep = " | ")%>% 
   dplyr::distinct() %>% 
   tidyr::separate(gene_id, c("gene_name","gene_id","gene_biotype"), sep = " \\| ")
##利用一些gtf注释文件的时候因为ensembl的版本号问题总会有很多重复行,在去除掉版本号之后我们就要根据需要去除这些重复项

字符串操作stringr

上面讲了这么多有关于矩阵操作的方法,而stringr主要负责对于字符串进行处理,有了这个工具,我们可以批量对基因名进行合并,修改,删减等操作。

str_c() 函数将值与指定的分隔符连接在一起。collapse参数指定是否将多个对象合并为单个字符串。

colnames(tmp) %>% str_c( '/')
[1] "rowname/"    "SRR1039508/" "SRR1039509/" "SRR1039512/" "SRR1039513/" "SRR1039516/" "SRR1039517/" "SRR1039520/"
[9] "SRR1039521/"

colnames(tmp) %>% str_c(collapse = '_')
[1] "rowname_SRR1039508_SRR1039509_SRR1039512_SRR1039513_SRR1039516_SRR1039517_SRR1039520_SRR1039521"

str_split()str_c()相反,它是按照指定分隔符将字符串分隔开,常见与消除ensembl gene id后面的版本号。

str_split(rownames(tmp),'[.]',simplify = T)[,1]
##按.将基因名分开,并保留分隔后的第一列

str_sub()对字符串进行提取操作,可以指定位置。

tmp %>% pull(rowname) %>% str_sub(start = 11,end = 15)
[1] "00003" "00005" "00419" "00457" "00460" "00938" "00971" "01036" "01084" "01167" "01460" "01461" "01497" "01561" "01617"
 [16] "01626" "01629" "01630" "01631" "02016" "02079" "02330" "02549" "02586" "02587" "02726" "02745" "02746" "02822" "02834"
 [31] "02919" "02933" "03056" "03096" "03137" "03147" "03249" "03393" "03400" "03402" "03436" "03509" "03756" "03987" "03989"
 [46] "04059" "04139" "04142" "04399" "04455" "04468" "04478" "04487" "04534" "04660" "04700" "04766" "04776" "04777" "04779"
 [61] "04799" "04809" "04838" "04846" "04848" "04864" "04866" "04897" "04939" "04948" "04961" "04975" "05001" "05007" "05020"
 [76] "05022" "05059" "05073" "05075" "05100" "05102" "05108" "05156" "05175" "05187" "05189" "05194" "05206" "05238" "05243"
 [91] "05249" "05302" "05339" "05379" "05381" "05421" "05436" "05448" "05469" "05471"

str_replace()字符串替换操作,可以指定字符串并进行替换,支持使用正则表达式,类似于sub(),只会替换第一个识别的字符,如果想要实现全局替换,可以使用str_replace_all(),等同于gsub()

tmp %>% pull(rowname) %>% str_replace_all('^ENSG','QQQQ') %>% head()
[1] "QQQQ00000000003" "QQQQ00000000005" "QQQQ00000000419" "QQQQ00000000457" "QQQQ00000000460" "QQQQ00000000938"

str_to_()在数据整理过程中,需要确保列的所有值都具有相同的大小写,因为R区分大小写。使用str_to_函数族,包括str_to_upper(),str_to_lower()和str_to_title(),可以很简单的修改任何值的大小写。

str_detect()函数标识向量的每个元素中是否存在模式。此函数返回一个逻辑值,表示每个元素是否与模式匹配,如果需要返回与模式匹配的值,则使用str_subset()函数。

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