RNA-seq分析(STAR-RSEM-DESeq2)

一、准备RNA-seq数据

  • 需要参考基因组文件,注释文件,样本的fastq.gz文件
  • 检查fastq.gz是否完整
md5sum sample.fastq.gz > md5.txt
md5sum -c md5.txt
#结果为OK既可,否则再次准备RNA-seq文件

二、fastqc生成质量报告(multiqc 提高查看效率)

  • fastqc为每个样本生成质量报告,可视化的报告测序数据的质量,为下一步质量控制做准备。
  • multiqc可以将多个fastqc得到的质量报告合成一份质量报告。如果有很多fastqc文件时,一份一份翻看效率很低,此时用mutilqc合并成一份报告可以提高效率
1. 安装fastqc和multiqc
conda install fastqc

conda install multiqc
2. 使用fastqc生成质量报告
##fastqc的几种使用方式

#多线程同时处理
ls */*fastq.gz | xargs -I []  nohup fastqc [] &

#批量处理
fastqc *fastq.gz 

#单个处理
fastqc Sample.fastq.gz

3.使用multiqc命令合并指定目录下的html文件,并生成一个html文件(multiqc可以自动检测目录下的html文件,所以只需输入目录)
multiqc <指定目录>

三、trimmomatic质量控制

  • 顾名思义,根据fastqc生成的质量报告对测序数据进行质量控制。比如,去除接头和低质量碱基,以减小噪点对比对和定量的影响
1.安装trimmomatic
conda install trimmomatic
2.trimmomatic参数
PE/SE             设定对Paired-End或Single-End的reads进行处理,其输入和输出参数稍有不一样。
-threads          设置多线程运行数
-phred33          设置碱基的质量格式,可选pred64,不设置这个参数,软件会自动判断输入文件是哪种格式
-trimlog          指定过滤日志文件名,日志中包含以下四列内容:read ID、过滤之后剩余序列长度、过滤之后的序列起始碱基位置(序列开头处被切掉了多少个碱基)、过滤之后的序列末端碱基位置、序列末端处被剪切掉的碱基数。
                  #由于生成的trimlog文件中包含了每一条 reads 的处理记录,因此文件体积巨大(GB级别),如果后面不会用到 trim日志,建议不要使用这个参数
-basein           通常 PE 测序的两个文件,指定其中 R1 文件名,软件会推测出 R2 的文件名,但是这个功能实测并不好用,建议不用-basein参数,直接指定两个文件名(R1 和 R2)作为输入
-baseout          输出文件有四个,使用 -baseout 参数指定输出文件的 basename,软件会自动为四个输出文件命名,过滤之后双端序列都保留的就是 paired,反之如果其中一端序列过滤之后被丢弃了另一端序列保留下来了就是 unpaired(即 成对的clean reads, 未成对的正向序列以及未成对的反向序列)
                  #一般情况下,若paired reads百分比占90%以上,可只对paired reads进行比对分析
ILLUMINACLIP:TruSeq3-PE.fa:2:30:10:8:true
                  切除adapter序列。参数后面分别接adapter序列的fasta文件:第一步 seed 搜索时允许的最大错配碱基个数2:palindrome模式下匹配碱基数阈值30:simple模式下的匹配碱基数阈值10(7-15之间):palindrome 模式允许切除的最短接头序列为 8bp(默认值):palindrome 模式去除与 R1 完全反向互补的 R2(默认去除false),但在有些情况下,例如需要用到 paired reads 的 bowtie2 流程,就要将这个参数改为 true,否则会损失一部分 paired reads。
                  #按照规定顺序,ILLUMINACLIP 各个参数之间以冒号分开,PE测序需要注意最后一个参数。对于SE测序最后两个参数可以不设置
LEADING:3         切除首端碱基质量小于3的碱基
                  #Illumina平台有些低质量的碱基质量值被标记为 2 ,所以设置为3可以过滤掉这部分低质量碱基。
TRAILING:3        切除尾端碱基质量小于3的碱基
SLIDINGWINDOW:15:20
                  滑窗质量过滤,一般一个read的低质量序列都是集中在末端,也有很少部分在开头。从5'端开始进行滑动,当滑动位点周围一段序列(window)的平均碱基低于阈值,则从该处进行切除。Windows的size是15个碱基(一般设置在10-30之间),其平均碱基质量小于20,则切除
MINLEN:50         可被保留的最短reads长度,应根据原始序列的长度而定
HEADCROP:<length> 在reads的首端切除指定的长度
CROP:<length>     保留reads到指定的长度
TOPHRED33         将碱基质量转换为pred33格式
TOPHRED64         将碱基质量转换为pred64格式

3.使用trimmomatic质量控制
trimmomatic PE -threads 16 \ #PE指双端测序   -threads指使用几个线程
./01raw_data/sample_R1.fastq.gz ./01raw_data/sample_R2.fastq.gz \ #待质控样本的reads1和reads2文件
./02clean_data/sample_paired_clean_R1.fq.gz \#reads1中可以和read2配对的reads
./02clean_data/sample_unpair_clean_R1.fq.gz \#reads1中不可以和read2配对的reads 
./02clean_data/sample_paired_clean_R2.fq.gz \#reads2中可以和read1配对的reads 
./02clean_data/sample_unpair_clean_R2.fq.gz \#reads2中不可以和read1配对的reads
ILLUMINACLIP:~/miniconda3/share/trimmomatic-0.39-2/adapters/TruSeq2-PE.fa:2:30:10:1:true \
LEADING:3 TRAILING:3 SLIDINGWINDOW:4:20 MINLEN:50 TOPHRED33

4.可能出现的接头不适配的问题
①判断需要哪种接头文件

fastqc报告会给出可能的接头来源,如下图


接头来源
  • "Possible Source"是"Illumina Single End" 或 "Illumina Paired End" 时,根据自己是双端测序还是单端测序选择"TruSeq2-SE.fa" 或 "TruSeq2-PE.fa"
  • "Possible Source"是"TruSeq Universal Adapter" 或 "TruSeq Adapter, index..." 时,根据自己是双端测序还是单端测序选择"TruSeq3-SE.fa" 或 "TruSeq3-PE.fa"
②接头文件选择
(base) [xxx@ln01 adapters]$ pwd
#接头文件路径
/home/xxx/miniconda3/share/trimmomatic-0.39-2/adapters 
(base) [xxx@ln01 adapters]$ ls -lh
#接头文件一共有6类,根据fastqc给的接头报告选择相应的接头文件
-rw-rw-r-- 2 xxx xxx 239 Mar 28  2021 NexteraPE-PE.fa
-rw-rw-r-- 2 xxx xxx 538 Mar 28  2021 TruSeq2-PE.fa
-rw-rw-r-- 2 xxx xxx 142 Mar 28  2021 TruSeq2-SE.fa
-rw-rw-r-- 2 xxx xxx 259 Mar 28  2021 TruSeq3-PE-2.fa
-rw-rw-r-- 2 xxx xxx  93 Mar 28  2021 TruSeq3-PE.fa
-rw-rw-r-- 2 xxx xxx 119 Mar 28  2021 TruSeq3-SE.fa

  • 把所需的接头文件的绝对路径放在 "ILLUMINACLIP:" 之后

四、STAR比对

  • STAR可以将质控后的fastq.gz文件比对到参考基因组上,为后续的定量准备文件。STAR比对时,需要先用STAR构建他自己可以识别的索引文件,之后再比对
1.安装STAR
conda install STAR
2.构建索引
STAR --runThreadN 8 \#使用的线程,可根据电脑配置自行更改
--runMode genomeGenerate \#工作模式(建立索引)
--genomeDir 03star_index/ \#索引文件存储位置
--genomeSAindexNbases 12 \#报错,14太大,需要用12
--genomeFastaFiles 00ref/Brapa.genome.fasta \ #参考基因组
--sjdbGTFfile 00ref/Brapa.genome.gtf \ #注释文件
--sjdbOverhang 149 #一般为reads长度-1(150-1)

3.比对
STAR --runThreadN 16 --genomeDir 03star_index/ \ #索引文件所在目录
--readFilesCommand zcat \ #执行解压缩
--readFilesIn02clean_data/sample_paired_clean_R1.fastq.gz \
02clean_data/sample_paired_clean_R2.fastq.gz \ #输入文件
--outFileNamePrefix 04STAR_out/sample \#输出目录及文件前缀
--outSAMtype BAM SortedByCoordinate \#指定输出bam 文件并排序
--outBAMsortingThreadN 16 \ #设置排序中的线程数
--quantMode TranscriptomeSAM GeneCounts #将上面基因组比对的信息转化为转录本比对的信息,count
# --quantMode TranscriptomeSAM will output alignments translated into  tran-script coordinates,为了使用RSEM 进行定量分析做准备

4.输出文件
  • 一共有7个文件
-rw-r--r-- 1 xxx xxx 2.7G Dec  5 00:43 sampleAligned.sortedByCoord.out.bam
-rw-r--r-- 1 xxx xxx 2.4G Dec  5 00:34 sampleAligned.toTranscriptome.out.bam
-rw-r--r-- 1 xxx xxx 2.0K Dec  5 00:43 sampleLog.final.out
-rw-r--r-- 1 xxx xxx 1.4M Dec  5 00:43 sampleLog.out
-rw-r--r-- 1 xxx xxx 6.5K Dec  5 00:43 sampleLog.progress.out
-rw-r--r-- 1 xxx xxx 789K Dec  5 00:35 sampleReadsPerGene.out.tab
-rw-r--r-- 1 xxx xxx 6.1M Dec  5 00:35 sampleSJ.out.tab

五、RSEM定量

  • RSEM定量时,同样需要先构建RSEM可以识别的索引文件,之后才可以进行定量
1.安装
conda install rsem
2.构建索引
rsem-prepare-reference \
--gtf 00ref/Brapa.genome.gtf \#参考基因组的注释文件
00ref/Brapa.genome.fasta \#参考基因组
05rsem_index/Brapa_genome #索引文件存储位置

3.定量
rsem-calculate-expression \
--paired-end \ #双端测序
--no-bam-output \ #不输出bam结果(bam是一种文件格式,sam -> bam)
--alignments -p 16 -q ./04STAR_out/sampleAligned.toTranscriptome.out.bam \#比对所用的线程和输入文件
./05rsem_index/Brapa_genome \#索引文件所在目录及其前缀
./06rsem_out/sample_rsem #输出目录及文件前缀

4.输出文件
  • 一共有2个文件,一个目录。其中的两个文件sample_rsem.genes.results 和 sample_rsem.isoforms.results分别记录gene水平和转录本水平的定量结果。区别在于gene_id和transcript_id在第一列还是第二列
-rw-r--r-- 1 xxx xxx 2.2M Dec  5 11:39 sample_rsem.genes.results
-rw-r--r-- 1 xxx xxx 2.4M Dec  5 11:39 sample_rsem.isoforms.results
drwxr-xr-x 1 xxx xxx 4.0K Dec  5 11:39 sample_rsem.stat

  • sample_rsem.genes.results
gene_id transcript_id(s)        length  effective_length        expected_count  TPM     FPKM
Bra000001       Bra000001.1     1515.00 1319.96 2.00    0.08    0.10
Bra000002       Bra000002.1     1089.00 893.96  45.00   2.63    3.41
Bra000003       Bra000003.1     570.00  375.00  115.00  16.05   20.77
Bra000004       Bra000004.1     375.00  180.60  42.00   12.17   15.75
Bra000005       Bra000005.1     1434.00 1238.96 1522.50 64.29   83.25
Bra000006       Bra000006.1     312.00  118.83  613.00  269.90  349.45
Bra000007       Bra000007.1     711.00  515.97  59.00   5.98    7.75
Bra000008       Bra000008.1     882.00  686.96  12.00   0.91    1.18
Bra000009       Bra000009.1     657.00  461.97  1478.77 167.48  216.85

  • sample_rsem.isoforms.results
transcript_id   gene_id length  effective_length        expected_count  TPM     FPKM    IsoPct
Bra000001.1     Bra000001       1515    1319.96 2.00    0.08    0.10    100.00
Bra000002.1     Bra000002       1089    893.96  45.00   2.63    3.41    100.00
Bra000003.1     Bra000003       570     375.00  115.00  16.05   20.77   100.00
Bra000004.1     Bra000004       375     180.60  42.00   12.17   15.75   100.00
Bra000005.1     Bra000005       1434    1238.96 1522.50 64.29   83.25   100.00
Bra000006.1     Bra000006       312     118.83  613.00  269.90  349.45  100.00
Bra000007.1     Bra000007       711     515.97  59.00   5.98    7.75    100.00
Bra000008.1     Bra000008       882     686.96  12.00   0.91    1.18    100.00
Bra000009.1     Bra000009       657     461.97  1478.77 167.48  216.85  100.00

六、构建表达矩阵

可以直接使用RSEM构建表达矩阵。表达矩阵是以sample_rsem.genes.results的expected_count列构建的

1.构建矩阵

rsem-generate-data-matrix *rsem.genes.results > output. matrix

2.输出结果
(base) [xxx@ln01 L7_24h-vs-L7_CK]$ head L7_24h-vs-L7_CK.matrix
        "16group/L7_24h-vs-L7_CK/L7_24h_1/L7_24h_1rsem.genes.results"   "16group/L7_24h-vs-L7_CK/L7_24h_2/L7_24h_2rsem.genes.results"   "16group/L7_24h-vs-L7_CK/L7_24h_3/L7_24h_3rsem.genes.results"     "16group/L7_24h-vs-L7_CK/L7_CK_1/L7_CK_1rsem.genes.results"     "16group/L7_24h-vs-L7_CK/L7_CK_2/L7_CK_2rsem.genes.results"       "16group/L7_24h-vs-L7_CK/L7_CK_3/L7_CK_3rsem.genes.results"
"Bra000001"     2.00    2.00    8.00    8.00    19.00   21.00
"Bra000002"     38.00   45.00   46.00   67.00   62.00   46.00
"Bra000003"     169.00  115.00  93.00   185.00  161.00  183.00
"Bra000004"     17.00   42.00   16.00   22.00   21.00   26.00
"Bra000005"     1425.79 1522.50 1186.24 1151.77 1059.85 1278.12
"Bra000006"     753.00  613.00  567.00  525.00  439.00  619.00
"Bra000007"     35.00   59.00   33.00   55.00   57.00   42.00
"Bra000008"     1.00    12.00   8.00    12.00   10.00   16.00
"Bra000009"     1651.77 1478.77 1346.60 666.35  831.43  959.23

表达矩阵的列名是以输入文件的路径所命名的,所以需要根据自己的需求进行修改,提供一个我修改列名的代码

sample="L7_24h-vs-L7_CK"
awk 'BEGIN{printf"geneid\t'${sample%%-*}'_1\t'${sample%%-*}'_2\t'${sample%%-*}'_3\t'${sample##*-}'_1\t'${sample##*-}'_2\t'${sample##*-}'_3\n"} /Bra/{print $0}' ./16group/${sample}/${sample}.matrix \
> ./16group/${sample}/${sample}_deseq2.txt

七、差异基因分析

1.在Rstudio中安装DESeq2
if (!requireNamespace("BiocManager", quietly = TRUE))
    install.packages("BiocManager")
library(BiocManager)
install.packages("DESeq2")

2.分析
##批量处理
library(DESeq2)
library(stringr)
library(dbplyr)

file_name <- c("L7_24h-vs-L7_CK","L7_24h-vs-L7_Re24h",
               "L7_24h-vs-Le_24h","L7_3h-vs-L7_24h",
               "L7_3h-vs-L7_CK","L7_3h-vs-L7_Re24h",
               "L7_3h-vs-Le_3h","L7_CK-vs-Le_CK",
               "L7_Re24h-vs-L7_CK","L7_Re24h-vs-Le_Re24h",
               "Le_24h-vs-Le_CK","Le_24h-vs-Le_Re24h",
               "Le_3h-vs-Le_24h","Le_3h-vs-Le_CK",
               "Le_3h-vs-Le_Re24h","Le_Re24h-vs-Le_CK")

for ( i in 1:16  ) {
##提取所比较的样本名字,在控制条件部分设置level。level高的为控制组,低的为参照组
#将 - 看为分隔符,将file_name分为三个部分,[[1]][1]为第一部分,[[1]][3]为第三部分
sample <- str_split(file_name[i],"-")
sample1 <- sample[[1]][1]
sample2 <- sample[[1]][3]

# read.table ,文件有header,第一列为row.name
input_data <- read.table(paste0(file_name[i],'_deseq2.txt'),
                         header = TRUE, row.names = 1)

# 取整,函数round
round_data <-round(input_data,digits = 0)

# 准备文件
# as.matrix 将输入文件转换为表达矩阵
count_data <- as.matrix(round_data)

# 控制条件:因子。level高的为控制组,低的为参照组。logFC=(控制组) / (参照组)
condition <- factor(c(rep(sample1, 3), rep(sample2, 3)),levels = c(sample2,sample1))

# input_data根据控制条件构建data.frame
coldata <- data.frame(row.names=colnames(count_data),
                      condition)


# build deseq input matrix 构建输入矩阵
#countData作为矩阵的input_data;colData Data.frame格式;
#控制条件design;
dds <- DESeqDataSetFromMatrix(
  countData=count_data,colData=coldata, design=~condition)

#构建dds对象
dds <- DESeq(dds)

# 提取结果
#dds dataset格式转换为DESeq2 中result数据格式,矫正值默认0.1
res <- results(dds,alpha=0.05)

#查看res(DESeqresults格式),可以看到上下调基因
summary(res)

# 将经过矫正的表达量结果加进去;
res$up_down <- ifelse(res$log2FoldChange=="NA", "NA", ifelse(res$log2FoldChange<0, "down", "up"))
#resdata <- merge(as.data.frame(res), as.data.frame(counts(dds, normalized=TRUE)),by="row.names",sort=FALSE)
resdata <- merge(as.data.frame(res),as.data.frame(counts(dds,normalized=TRUE)),
by="row.names",sort=FALSE)

#将fpkm加入分析结果中
#resdata <- merge(as.data.frame(res), as.data.frame(read.table(paste0(file_name[i],'_fpkm.txt'),
#                                                            header = TRUE, row.names = #1)),by="row.names",sort=FALSE)
names(resdata)[1] <- "Gene"

# 输出结果,保存为csv文件

resdata$padj[is.na(resdata$padj)] <- 1
write.csv(resdata,file=paste0(file_name[i],'.csv'),sep = "\t",quote = F, row.names = F)

#筛选出 padj < 0.05, logFC >= 1 的基因
deg <- subset(resdata, resdata$padj <= 0.05 & abs(resdata$log2FoldChange) >= 1 )

#当与fpkm合并后,可能会出现fpkm的和为零但是显著差异的情况,这种基因需要去掉。
#deg <- subset(resdata, resdata$padj <= 0.05 & abs(resdata$log2FoldChange) >= 1 & apply(resdata[,9:14], 1, sum) > 0 )

write.csv(deg,file=paste0(file_name[i],'-deg-padj-0.05-logFC-1.csv'),sep = "\t",quote = F, row.names = F)
}

七、结语

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

推荐阅读更多精彩内容