美文网首页RNA-seq
开心回归~复习下之前的学习内容

开心回归~复习下之前的学习内容

作者: 刘小泽 | 来源:发表于2018-11-12 23:45 被阅读57次

    刘小泽写于18.11.12 半年之前我和花花成立了“生信星球”,转眼过得好快,我们每天都能和爱生信的小伙伴们交流,还办了9期培训,灰常开心

    终于可以回归写推送了,连续半个月奋战两篇文章,好累,真不如学知识写推送轻松。时隔半月,有点忘记,但是重新学一次,又能学到新知识,还是不错的

    数据准备:

    数据地址在 http://www.ncbi.nlm.nih.gov/geo/download/?acc=GSE63310&format=file

    files <- c("GSE63310_RAW/GSM1545535_10_6_5_11.txt", 
               "GSE63310_RAW/GSM1545536_9_6_5_11.txt",
               "GSE63310_RAW/GSM1545538_purep53.txt",
               "GSE63310_RAW/GSM1545539_JMS8-2.txt",
               "GSE63310_RAW/GSM1545540_JMS8-3.txt",
               "GSE63310_RAW/GSM1545541_JMS8-4.txt",
               "GSE63310_RAW/GSM1545542_JMS8-5.txt",
               "GSE63310_RAW/GSM1545544_JMS9-P7c.txt", 
               "GSE63310_RAW/GSM1545545_JMS9-P8c.txt")
    # 读取第一个文件,看下前5行
    read.delim(files[1], nrow=5)
    #>    EntrezID GeneLength Count
    #> 1    497097       3634     1
    #> 2 100503874       3259     0
    #> 3 100038431       1634     0
    #> 4     19888       9747     0
    #> 5     20671       3130     1
    

    批量读取+转换:

    • 方法一:一次性读取全部,用readDGE函数
    suppressMessages(library(limma))
    suppressMessages(library(edgeR))
    #输入基因名和count的列
    x <- readDGE(files, columns = c(1,3)) 
    # x包含了两部分信息:sample和count
    class(x)
    #> [1] "DGEList"
    #> attr(,"package")
    #> [1] "edgeR"
    dim(x)
    #> [1] 27179     9
    
    • 方法二:分别读取,再用DGEList函数转换全部

    转换下样本信息

    存储样本与cell type(basal,LP,ML)/ genotype(wild-type, knockout)/ phenotype(status, sex, age)/
    sample treatment(drug, control)/ batch effect (date, lane)

    # 输入start、stop 位置
    samplenames <- substring(colnames(x), 25, nchar(colnames(x))) 
    samplenames
    #> [1] "10_6_5_11" "9_6_5_11"  "purep53"   "JMS8-2"    "JMS8-3"    "JMS8-4"   
    #> [7] "JMS8-5"    "JMS9-P7c"  "JMS9-P8c"
    #去掉列名的重复项,重新命名
    colnames(x) <- samplenames 
    #添加分组信息,比如细胞类型
    group <- as.factor(c("LP", "ML", "Basal", "Basal", "ML", "LP",
    "Basal", "ML", "LP"))
    x$samples$group <- group
    # 添加lane信息
    lane <- as.factor(rep(c("L004","L006","L008"), c(3,4,2))) 
    x$samples$lane <- lane
    x$samples
    #>                                           files group lib.size
    #> 10_6_5_11 GSE63310_RAW/GSM1545535_10_6_5_11.txt    LP 32863052
    #> 9_6_5_11   GSE63310_RAW/GSM1545536_9_6_5_11.txt    ML 35335491
    #> purep53     GSE63310_RAW/GSM1545538_purep53.txt Basal 57160817
    #> JMS8-2       GSE63310_RAW/GSM1545539_JMS8-2.txt Basal 51368625
    #> JMS8-3       GSE63310_RAW/GSM1545540_JMS8-3.txt    ML 75795034
    #> JMS8-4       GSE63310_RAW/GSM1545541_JMS8-4.txt    LP 60517657
    #> JMS8-5       GSE63310_RAW/GSM1545542_JMS8-5.txt Basal 55086324
    #> JMS9-P7c   GSE63310_RAW/GSM1545544_JMS9-P7c.txt    ML 21311068
    #> JMS9-P8c   GSE63310_RAW/GSM1545545_JMS9-P8c.txt    LP 19958838
    #>           norm.factors lane
    #> 10_6_5_11            1 L004
    #> 9_6_5_11             1 L004
    #> purep53              1 L004
    #> JMS8-2               1 L006
    #> JMS8-3               1 L006
    #> JMS8-4               1 L006
    #> JMS8-5               1 L006
    #> JMS9-P7c             1 L008
    #> JMS9-P8c             1 L008
    

    增加一个基因注释信息

    基因注释涉及到ID转换,方法一:clusterProfiler

    # 数据集中使用的是EntrezID
    suppressMessages(library(Mus.musculus, supr))
    suppressMessages(library(clusterProfiler))
    geneid <- rownames(x)
    # 但是好像没有染色体信息
    genes <- bitr(geneid, OrgDb = Mus.musculus, fromType = "ENTREZID", toType = "SYMBOL" )
    #> 'select()' returned 1:1 mapping between keys and columns
    #> Warning in bitr(geneid, OrgDb = Mus.musculus, fromType = "ENTREZID", toType
    #> = "SYMBOL"): 3.52% of input gene IDs are fail to map...
    head(genes)
    #>    ENTREZID  SYMBOL
    #> 1    497097    Xkr4
    #> 2 100503874 Gm19938
    #> 3 100038431 Gm10568
    #> 4     19888     Rp1
    #> 5     20671   Sox17
    #> 6     27395  Mrpl15
    

    方法二:biomaRt(属于Ensembl)

    suppressMessages(library(Mus.musculus))
    geneid <- rownames(x)
    # 增加Symbol名称和染色体信息
    genes <- select(Mus.musculus, keys=geneid, 
                    columns=c("SYMBOL", "TXCHROM"),keytype="ENTREZID")
    #> 'select()' returned 1:many mapping between keys and columns
    head(genes)
    #>    ENTREZID  SYMBOL TXCHROM
    #> 1    497097    Xkr4    chr1
    #> 2 100503874 Gm19938    <NA>
    #> 3 100038431 Gm10568    <NA>
    #> 4     19888     Rp1    chr1
    #> 5     20671   Sox17    chr1
    #> 6     27395  Mrpl15    chr1
    

    需要注意的是:ID转换中可能出现多个同样的Entrez ID,比如某个基因出现在不同染色体,
    就会在不同位置出现同一个ID。这种情况需要先检查下

    dup <- genes$ENTREZID[duplicated(genes$ENTREZID)]
    genes[genes$ENTREZID %in% dup,][1:10,]
    #>        ENTREZID    SYMBOL TXCHROM
    #> 5360  100316809 Mir1906-1   chr12
    #> 5361  100316809 Mir1906-1    chrX
    #> 9563      12228      Btg3   chr16
    #> 9564      12228      Btg3   chr17
    #> 11350    433182     Eno1b    chr4
    #> 11351    433182     Eno1b   chr18
    #> 11543 100217457  Snord58b   chr14
    #> 11544 100217457  Snord58b   chr18
    #> 13226    735274  Mir684-1    chr2
    #> 13227    735274  Mir684-1    chr5
    # 出现多次的基因只统计出现第一次的,得到的是一个位置向量,即位于多少行
    mat <- match(geneid, genes$ENTREZID)
    genes <- genes[mat,]
    #再次验证
    genes[genes$ENTREZID %in% dup,][1:5,]
    #>        ENTREZID    SYMBOL TXCHROM
    #> 5360  100316809 Mir1906-1   chr12
    #> 9563      12228      Btg3   chr16
    #> 11350    433182     Eno1b    chr4
    #> 11543 100217457  Snord58b   chr14
    #> 13226    735274  Mir684-1    chr2
    x$genes <- genes
    

    数据预处理

    raw-count标准化

    不管是差异分析还是其他用到count值的相关分析,如WGCNA,都基本不直接用原始count值,原因是这个数值容易受到外界的干扰。一般来讲,影响raw count的有两个因素:

    • 测序深度
      这个比较好理解,深度越大,得到的reads数就越多,当然count差异就越大
    • RNA的组织/时间特异性
      不同时期基因表达量是不一样的,很难保证两组样本中RNA是同一时期的

    因此需要先对测序深度做一个转换,也就是所谓的“标准化”,减少外在影响

    比较流行的标准化方式有:counts per million (CPM), log2-counts per million (log-CPM), reads per kilobase of transcript per million (RPKM), fragments per kilobase of transcript per million (FPKM); 其中CPM与logCPM没有考虑基因长度(要求略低),直接对矩阵进行转换。

    # edegR中的CPM与log-CPM
    cpm <- cpm(x)
    lcpm <- cpm(x, log=TRUE)
    # 如果用edegR中的rpkm,需要提供gene length信息
    # 用TMM方法
    x <- calcNormFactors(x, method = "TMM")
    

    去掉不表达基因

    所有的表达量数据都存在表达与非表达基因,拿到表达量数据先看下非表达基因占多少。

    #这里有9组样本,因此可以统计9组中表达量都为0的基因
    table(rowSums(x$counts==0)==9)
    #> 
    #> FALSE  TRUE 
    #> 22026  5153
    

    基因必须至少在一组处理中或者任意3个样本中有表达量才能被保留。当然,非表达的需要去除,以减少后续分析压力

    keep.exprs <- rowSums(cpm>1)>=3
    # 行代表基因,列代表样本;这里选择全部样本
    x <- x[keep.exprs,, keep.lib.sizes=FALSE]
    dim(x)
    #> [1] 14165     9
    

    基因表达分布的标准化

    使用trimmed mean of M-values(TMM),也就是目前认为最准确的标准化方式
    为了解决样本间由于组织、时间特异性而引起的误差,TMM首先从所有样本中挑选一个样本作为参照,当对其他样本进行归一化时,就只考虑参照样本和待归一化的样本间共有的RNA
    一般来讲,mRNA数据使用TMM就可以【但是单细胞测序及全转录组一般是不行的,因为它们的差异表达比较多】

    x <- calcNormFactors(x, method = "TMM")
    

    非监督式样本聚类

    在正式开始差异分析之前,可以使用非监督式学习处理一下:

    什么是非监督?

    将数据按相似度聚类(clustering)成不同的分组或者用降维的方式,保留基本的数据结构,同时压缩数据。包含了K 均值聚类、层次聚类、主成分分析(PCA)和奇异值分解(SVD)

    • K均值聚类
      目标是将数据点分组,让不同聚类中的数据点不同,同一聚类中的数据点类似;使用这种方法希望结果的数据点被聚类为 K 组。K 大分组就小,就有更多粒度;K 小时,分组就大,粒度更少(可以理解成零散程度)

    比如一个领导者一般气场比较大,周围会有一些像被吸附了的帮手;如果这样的领导只有一个,那么群众们都围着他转;如果英雄辈出,那么各自会形成一个小中心圈,分别集结一小帮人

    • 层次聚类
      我们日常说的“做个聚类树”,就是指的这个。目标是构建一个树状层次,让相似的离得更近。它是这么做的:
    1. 先从 第N 个聚类开始,每个数据点一个聚类;
    2. 将彼此靠得最近的两个聚类融合为一个,那么现在有 N-1 个聚类
    3. 重新计算这些聚类之间的距离(方法很多,其中一种“average-linkage clustering”将两个聚类之间的距离看作是聚类中元素所有距离的平均值)
    4. 重复2-3,再选择聚类的数量(就是要将整体分成几部分),画条水平线
    • 降维
      两种办法:主成分分析和奇异值分解
    1. 主成分分析:假设我们现在有1w维空间的数据,然后怎么样才能知道数据间的联系呢,哪些比较强势?我们可以将原始数据映射到另一个更紧凑的空间中(比如只有100维),减少了复杂度(也就是维度),还保证了原始结构不变(即方差不变)
    2. 奇异值分解(SVD)
      如果说我们的数据是一个a X b的大型矩阵,通过SVD将大矩阵拆分成几个小矩阵的乘积,从中找一个对角矩阵叫做“奇异值”,之所以奇异,是因为它可以用于压缩原来的矩阵。如果我们丢弃奇异值中最小的 20% 以及其他矩阵中相关的列,我们就可以节省大量空间,并能很好地表示原来的矩阵
    这里怎么做?

    这里采用limma的multidimensional scaling (MDS) plot即“多维尺度变换”,这个会用非监督式显示样本之间的异同,在正式差异分析前帮助我们判断潜在的差异样本。它的结果会将所有样本划分成几个维度,第一维度的样本代表了最大的差异,维度越往后,相似度就越大,差异分析的结果越不理想

    当实验设计中存在多个实验因子时,每个实验因子都要进行这几个维度的检测。这样做,还能看出哪个实验因子对差异表达的贡献最大,基本没什么影响的因子,就无法参与后续分析。

    suppressMessages(library(RColorBrewer))
    # 这里就用最简单的CPM值
    lcpm <- cpm(x, log=TRUE)
    par(mfrow=c(1,2))
    col.group <- group
    levels(col.group) <- brewer.pal(nlevels(col.group), "Set1") 
    col.group <- as.character(col.group)
    col.lane <- lane
    levels(col.lane) <- brewer.pal(nlevels(col.lane), "Set2") 
    col.lane <- as.character(col.lane)
    # 1、2维度
    plotMDS(lcpm, labels=group, col=col.group) 
    title(main="A. Sample groups")
    # 3、4维度
    plotMDS(lcpm, labels=lane, col=col.lane, dim=c(3,4)) 
    title(main="B. Sequencing lanes")
    

    欢迎关注我们的公众号~_~  
    我们是两个农转生信的小硕,打造生信星球,想让它成为一个不拽术语、通俗易懂的生信知识平台。需要帮助或提出意见请后台留言或发送邮件到Bioplanet520@outlook.com

    Welcome to our bioinfoplanet!

    相关文章

      网友评论

        本文标题:开心回归~复习下之前的学习内容

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