DADA2+Phyloseq分析16S-seq数据 2021-06-10

一. 16S-seq实验

所用示例数据使用Illumina公司两步PCR的方法进行扩增:

1st stage PCR, 使用含adaptor的16S rRNA基因的通用引物,比如505F-80R,799F-1192等;

2nd stage PCR, 使用含P5/P7,index,和adaptor的引物,给每个样品的序列加上特定的index

测序使用2x250bp双端测序。

Illumna 16S-seq实验流程

二. 安装分析所需要的软件

安装R语言

(1) RStudio | Open source & professional software for data science teams - RStudio

(2) R: The R Project for Statistical Computing (r-project.org)

安装分析包。

(1) R含有大量的分析包,统计分析、画图等packages可以直接通过R.studio菜单中的tools>install packages安装;或者使用以下命令:

install.packages("pkg-name")

(2) R中生物信息学常用的分析包来自bioconductor,需要先在R中安装BiocManager,再使用BiocManager安装分析包

install.packages("BiocManager")    # 安装BiocManager软件包

 BiocManager::install("dada2")       # 安装bioconductor中的dada2分析包

···

安装中可能会出现以下提示:

安装DADA2的提示

可输入a,表示update所有与dada2有关联的分析包。

(3) 本示例中需要安装以下软件包:dada2,phyloseq,ggplot2,DESeq2

(4) 分析开始前,在Rstudio读入所需的软件包

(5) 设置好工作目录:通过Rstudio的session>Set Working Directory>choose Directory设置

set working director

或者直接在终端中输入以下命令:

setwd("E:/teaching/da2-pipline")  #中间的路径需要根据自己的电脑修改


三、测序文件的处理

1. 首先查看以下收到的测序文件,常用的2x250bp测序结果会含两个文件,比如sample-R1.fq和sample-R2.fq,分别用R1和R2表示5'-和3'-测序结果,sample为原理提供的样品名。

测序结果文件

2. 将测序文件的信息读入R语言中。

以下示例中,现将测序结果所在的文件夹路径读入到path,然后将该文件夹下面所有以“-R1.fq”

#设置path保存测序文件所在的路径

path <- "Z:/dada2_pipline";

#以下命令会显示path保存的文件夹路径下所有文件名

list.files(path);

#以下命令显示path文件夹中,所有以-R1.fq结尾的文件,并排序

sort(list.files(path, pattern="-R1.fq", full.names = TRUE))

# 明白以上命令后,可运行下面的代码,将测序结果文件信息读入fnFs和fnRs

fnFs <- sort(list.files(path, pattern="-R1.fq", full.names = TRUE)) 

fnRs <- sort(list.files(path, pattern="-R2.fq", full.names = TRUE)) 

# 在Rstudio,可查看右上角中fnFs和FnRs的内容,是否为正确的测序文件名

#或者直接在Rstudio的控制终端,输入fnFs查看

该示例中,共有4个文件

3. 查看测序质量。

#查看测序质量

#绘制样品1-2测序质量的图片,并保存到plot_output

plot_output<-plotQualityProfile(fnFs[1:2]);

#查看图片, 注意右侧Plots窗口

plot_output;     

#绘制所有样品测序质量的图

plot_output<-plotQualityProfile(fnFs);   

plot_output;

#保存图片到当前目录

ggsave(filename="For_seq_qual.pdf",plot_output,

      width = 18, height = 6,

      units = "cm");

plotQualityProfile(fnRs);  #  绘制Rev测序的质量图片,可按上述代码保存图片

#移除暂时不用的plot_output

rm(plot_output);

输出结果,y轴为测序质量数据,x轴为测序循环数(即碱基位置)

关于测序质量图的注解

In gray-scale is a heat map of the frequency of each quality score at each base position. The mean quality score at each position is shown by the green line, and the quartiles of the quality score distribution by the orange lines. The red line shows the scaled proportion of reads that extend to at least that position (this is more useful for other sequencing technologies, as Illumina reads are typically all the same length, hence the flat red line).

4. 过滤接头和低质量序列

从上述的图中,以Q30为阈值,可以看出,Forward(R1)的整体质量都还可以;Reverse(R2)的测序质量稍低,平均来看,大概也在200bp左右出现了下降。

设置过滤后文件保存的位置

此示例中,是在原来path保存的目录下面,建立一个“filtered”的文件夹,用来保存过滤后的序列文件,文件名按照sample_F_filt.fastq.gz的模式命名,其中后面的.gz表示该文件是压缩文件。

#paste0()函数将sample.names中保存的样品名(即原来测序文件的前半部分)加上"_F_filt.fastq.gz"

paste0(sample.names, "_F_filt.fastq.gz");

#file.path()函数,将目录path,“filtered”,文件名用/连起来,

filtFs <- file.path(path, "filtered", paste0(sample.names, "_F_filt.fastq.gz"));

filtRs <- file.path(path, "filtered", paste0(sample.names, "_R_filt.fastq.gz"));

运行以下filterAndTrim函数,过滤低质量序列。out保存过滤信息。

在该示例中,

fnFs和fnRs为原始序列文件,filtFs和filtRs为过滤后的序列文件;

truncLen=c(208,200)表示分别去掉208(For测序结果)和200(rev测序结果)以后的碱基;

MaxN=0,切除末端的低质量序列后,得的的序列中不能再有N;

maxEE=c(2,2),序列的EE值不能低于maxEE,EE = sum(10^(-Q/10)). 比如200bp的序列,每个碱基的Q=30,EE=0.2.

rm.phix=TRUE,去除其中来自phix噬菌体的序列(测序反应中加入phix DNA作为对照);

compress=TRUE,压缩输出的序列文件。

如果需要切除5'端的引物序列,可以用加入trimLeft=c(N1,N2)。

out <- filterAndTrim(fnFs, filtFs, fnRs, filtRs, truncLen=c(208,200),

                    maxN=0, maxEE=c(2,2), truncQ=2, rm.phix=TRUE,

                    compress=TRUE, multithread=FALSE);

#查看过滤信息

head(out);

#查看过滤后的序列质量 

plotQualityProfile(filtFs); 

plotQualityProfile(filtRs);


过滤后的序列质量

5. 推断序列变异(Infer Sequence variant)

DADA2中,learnErrors程序“学习”输入数据中测序产生错误,并构建预测模型。

# 这里是DADA2比较神奇的地方, 它会从输入的数据中学习测序的误差。理论上,输入的数据越大,

# 学习模型越准确,需要的计算资源也越大

errF <- learnErrors(filtFs, multithread=FALSE);

errR <- learnErrors(filtRs, multithread=FALSE);

#绘制quality score与error frequency相关图形

plotErrors(errF, nominalQ=TRUE);

plotErrors(errF, nominalQ=TRUE);

Forward测序数据中,不同类型的突变频率与Q值之间的关系

然后利用该模型,去除测序产生的碱基替换、indel错误,来获得“真实”的序列(denoised sequence)。

> dadaFs <- dada(filtFs, err=errF, multithread=FALSE)

Sample 1 - 8382 reads in 4284 unique sequences.

Sample 2 - 9341 reads in 4959 unique sequences.

Sample 3 - 8866 reads in 4794 unique sequences.

Sample 4 - 8097 reads in 4720 unique sequences.

> dadaRs <- dada(filtRs, err=errR, multithread=FALSE)

Sample 1 - 8382 reads in 6273 unique sequences.

Sample 2 - 9341 reads in 5980 unique sequences.

Sample 3 - 8866 reads in 6526 unique sequences.

Sample 4 - 8097 reads in 6833 unique sequences.

将双端测序的reads合并

minOverlap

#将双端测序的reads合并

mergers <- mergePairs(dadaFs, derepFs, dadaRs, derepRs)

构建ASV table

> #构建sequence table,即OTU table或ASV

> #包含ASV,每一个ASV

> seqtab <- makeSequenceTable(mergers);

#表格的行、列数目。本示例中,有4行(4个样品);587列(587条ASV);

> dim(seqtab);

[1]   4 587

> seqtab[,1];

root_exp1 root_exp2 soil_exp1 soil_exp2 

      522       364         0         0 

> #ASV的长度信息统计

> table(nchar(getSequences(seqtab)));

去嵌合体(remove chimeras)

## 去PCR产生的嵌合体

seqtab.nochim <- removeBimeraDenovo(seqtab, method="consensus", multithread=TRUE, verbose=TRUE);

dim(seqtab.nochim);

 #计算每个样品中嵌合体的比例

apply(seqtab.nochim,1,sum)/apply(seqtab,1,sum);

#查看第一条ASV的序列(即第一列的标题)

colnames(seqtab)[1]

增加序列的物种信息

##给ASV序列赋予物种分类信息

## 分类数据库保存在当前目录的tax文件夹中(“./tax”)

## 如内存不够,可删除中间信息

rm(errF,errR,plot_output, seqtab,dadaFs,dadaRs,derepFs,derepRs);

taxa <- assignTaxonomy(seqtab.nochim, "./tax/silva_nr_v132_train_set.fa.gz", multithread=TRUE)

#增加species的信息。

taxa <- addSpecies(taxa, "./tax/silva_species_assignment_v132.fa.gz")

到此,序列的处理结束,接下来用phyloseq包分析微生物多样性信息。

四. 多样性分析

1. 将序列处理结果phyloseq的格式。

#构建样品信息表格

#本示例中。有两个root和soil两种材料,每个两个重复。

#查看sample names

sample.names;

samdf <- data.frame(rownames(seqtab.nochim),c("root","root","soil","soil"));

rownames(samdf)<- sample.names;

colnames(samdf)<-c("id","group")

samdf;


构建完成的样品信息表。id表示样品名字,与OTU table中的名字一致


2. 整理OTU table和taxa table,主要是将原来序列作为列标题的表格换为人工设定的OTU+数字

##整理OTU table(或ASV table)

# 上述脚本输出的seqtab.nochim表格中,列的标题是ASV的序列(非常长),在这里用简单的OTU+数字来代替

seqtab.nochim0<-seqtab.nochim;

colnames(seqtab.nochim0)<-paste(rep("OTU",ncol(seqtab.nochim)),1:ncol(seqtab.nochim),sep="");

## 同上,将taxa表格中的分类信息用OTU+数据来代替。

taxa0<-taxa

rownames(taxa0)<-paste(rep("OTU",ncol(seqtab.nochim)),1:ncol(seqtab.nochim),sep="");

head(taxa0);


## 将信息读入phyloseq所需的格式

ps <- phyloseq(otu_table(seqtab.nochim0, taxa_are_rows=FALSE),   sample_data(samdf),                tax_table(taxa0));

重构好的taxa0信息表格


3. 获取多样性信息

(1)alpha多样性

#可以开始查看多样性的信息

# 查看alpha多样性

estimate_richness(ps, measures =c("Observed", "Chao1", "ACE", "Shannon", "Simpson", "InvSimpson", "Fisher"));

#绘制alpha多样性的比较图

plot_richness(ps);

alpha多样性的输出


绘制alpha多样性信息

(2)对数据进行rarefaction平衡化后重新分析。

##rarefaction后重新估计多样性数据

set.seed(7)

#参考每个样品的序列总数

rowSums(otu_table(ps));

#最小值为3993,可将sample.size设为3993以下,进行rarefaction

ps.rarefy<-rarefy_even_depth(ps, sample.size=3900, replace=T);

#利用rarefactio的数据重新估计样品多样性

# 查看alpha多样性

estimate_richness(ps.rarefy, measures =c("Observed", "Chao1", "ACE", "Shannon", "Simpson", "InvSimpson", "Fisher"));

#绘制alpha多样性的比较图

plot_richness(ps);

#绘制热图

plot_heatmap(ps.rarefy, method = "NMDS", distance = "bray");

比较两次的输出结果


alpha多样性比较,每个样品序列总数通过rarefaction到3900


alpha多样性数据(rarefied to 3900 reads)

(3)beta多样性比较

绘制heatmap

#绘制热图

plot_heatmap(ps.rarefy, method = "NMDS", distance = "bray");

heatmap

PCA分析

#PCA分析

pslog<-transform_sample_counts(ps.rarefy, function(x) log(1+x));

out.log<-ordinate(pslog, method="NMDS", distance="bray");

plot_ordination(pslog, out.log, color="id", shape="group");

PCA分析

细菌组成

#绘制每个样品门水平的丰度信息

plot_bar(ps.rarefy,x="id", fill="Phylum");

#绘制丰度高的OTU代表的细菌Family

top20 <- names(sort(taxa_sums(ps.rarefy), decreasing=TRUE))[1:20];

ps.top20 <- transform_sample_counts(ps.rarefy, function(OTU) OTU/sum(OTU));

ps.top20 <- prune_taxa(top20, ps.top20);

plot_bar(ps.top20, x="id", fill="Family") + facet_wrap(~group, scales="free_x");

所有细菌门

#绘制丰度高的OTU代表的细菌Family

top20 <- names(sort(taxa_sums(ps.rarefy), decreasing=TRUE))[1:20];

ps.top20 <- transform_sample_counts(ps.rarefy, function(OTU) OTU/sum(OTU));

ps.top20 <- prune_taxa(top20, ps.top20);

plot_bar(ps.top20, x="id", fill="Family") + facet_wrap(~group, scales="free_x");


你可能感兴趣的:(DADA2+Phyloseq分析16S-seq数据 2021-06-10)