tidyverse

作者: nnlrl | 来源:发表于2019-07-30 15:57 被阅读57次

    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()函数。

    相关文章

      网友评论

        本文标题:tidyverse

        本文链接:https://www.haomeiwen.com/subject/esagrctx.html