复盘总结(三)

GTEX表达矩阵预处理

#设置工作路径
setwd("D:/gtex")
#初始化环境:
rm(list=ls())
#载入包:
library(data.table)
#获得要提取的样本ID:
sample_id <- read.table("sample.txt")
#再添加两个列名:
sample_id <-append(c("Name","Description"),sample_id)
#1.3G的表达谱文件路径:
GTExFile_path<-"./GTEx_Analysis_2017-06-05_v8_RNASeQCv1.1.9_gene_reads.gct"
#根据要提取的样本ID读入文件,skip前两行,select要读取的列,将第一行用作行名,分隔符Tab
GTEx_reads<-fread(GTExFile_path,sep="\t",header =T,skip = 2,select = sample_id)
#储存ensembl基因名与gene symbol的对应关系
#write.table(GTEx_reads[,1:2],file = "vs.tsv")
#删除前两列数据
GTEx_reads_ <- GTEx_reads[,-(1:2)]
#将字符改为数字
GTEx_reads_1 <- as.data.frame(lapply(GTEx_reads_,as.numeric))
#用ENSEMBL基因名作行名
vs <- read.table("vs.tsv")
rownames(GTEx_reads_1) <- vs[,1]
#更改列名,将字符改为数字不小心也更改了列名
colnames(GTEx_reads_1) <- colnames(GTEx_reads_)
#将数据保存为Rdata
save(GTEx_reads_1,file = "step_1.Rdata")

R语言学习:
1.append添加新的列。
2.R语言处理大规模数据速度不算快,通过安装其他包比如data.table可以提升读取处理速度。fread比read.table快4—5倍数。


原始数据

GTEX_reads

利用edgeR包对数据进行过滤以及归一化

#设置工作路径
setwd("D:/gtex")
#检查内存分配限制
memory.limit()
#设置为1G内存
memory.limit(1000000)
#初始化环境:
rm(list=ls())
#安装R包
if(F)
{
  if (!requireNamespace("BiocManager", quietly = TRUE))
    install.packages("BiocManager")
  BiocManager::install("edgeR")
}
library(edgeR)
#导入数据,创建DGElist
load(file = "step_1.Rdata")
x <- GTEx_reads_1
#x <- x[,1:560]
tmp <- read.csv(file = "sample_id&tissue.csv")
tmp_1 <- tmp[tmp[,1] %in% colnames(x),]
group = factor(tmp_1[,2])
y = DGEList(counts = x,group = group)
dim(y)
#手动过滤
#table(rowSums(y$counts==0)==1)
cut.off.cpm = 10*10**6/median(colSums(x))
 keep_cpm <- rowSums(cpm(y)>cut.off.cpm) >= 36
y_1 <- y[keep_cpm,, keep.lib.sizes=FALSE]
dim(y_1)
#自动过滤
if(F){
  keep.exprs <- filterByExpr(y, group=group)
  y_2 <- y[keep.exprs,, keep.lib.sizes=FALSE]
  dim(y_2)
}

y_3 <- calcNormFactors(y_1, method = "TMM")
#y_1$samples$norm.factors

#手动得到有效库
library("dplyr")
y_3[["samples"]] %>% mutate(lib.size=lib.size*norm.factors) -> y_3[["samples"]]

#计算过滤以及归一化之后的cpm值
cpm_3 <- cpm(y_3)
if(F)
{
  #voom从x中自动提取文库大小和归一化因子,以此将原始计数转换为log-CPM值。
  design = model.matrix(~group)
  v <- voom(y_3, design)
  #比较
  lcpm <- cpm(y_3, log=TRUE)
  #相似但是不完全相等,因为voom使用了更小的预先计数
}

#更改列名为组织
table <- as.data.frame(table(y_3[["samples"]][,1]))
b <- character()
for(i in 1:nrow(table) ){
  a <- rep(levels(y_3[["samples"]][,1])[i] , each = table[,"Freq"][i])
  b <- c(b,a)
}
colnames(cpm_3) <- b

#求每个基因在每个组织中表达的中位值
library(reshape2)
melt <- melt(cpm_3)
#aggregate(melt,by=list(melt$Var1,melt$Var2),FUN=median)
by <- group_by(melt,Var1,Var2) %>% summarise(median=median(value))
#数据长宽转换
library(tidyfst)
by %>% wider_dt("Var1",name = "Var2",value = "median") -> melt_1
save(melt_1,file = "step_2.Rdata")

样本信息:

> table(tmp_1[,2])

Adrenal Gland         Brain        Breast         Heart        Kidney         Liver 
          103           291           166           207            36           100 
         Lung        Muscle      Pancreas          Skin       Stomach        Testis 
          208           367           125           597           112           175 
       Uterus 
           48 

一共得到了13个组织,2535个样本。
低表达基因过滤:

> dim(y_1)
[1] 36692  2535

得到了36692个基因。

几点说明:
1.手动过滤的阈值选择:
此函数默认选取最小的组内的样本数量为最小样本数,保留至少在这个数量的样本中有10个或更多计数的基因。实际进行过滤时,使用的是CPM值而不是表达计数,以避免对总序列数大的样本的偏向性。在这个数据集中,总序列数的中位数是5.1千万,且10/51约等于0.2,所以filterByExpr函数保留在至少三个样本中CPM值大于等于0.2的基因。在我们的此次实验中,一个具有生物学意义的基因需要在至少三个样本中表达,因为三种细胞类型组内各有三个重复。过滤的阈值取决于测序深度和实验设计。如果样本总表达计数量增大,那么可以选择更低的CPM阈值,因为更大的总表达计数量提供了更好的分辨率来探究更多表达水平更低的基因。
对于在大多数样本中表达数量都很少的基因(往往是没有生物学意义的基因),需要进行过滤,这一步可以根据自己定义的标准过滤,edgeR推荐使用该包的CPM( count-per-million )值进行过滤。
在这里我也使用了cpm值进行手动的过滤。

2.归一化方法:
我们需要使用 edgeR 中的 calcNormFactors 函数,用 TMM(Robinson and Oshlack 2010) 方法进行归一化。此处计算得到的归一化系数被用作文库大小的缩放系数。当我们使用DGEList对象时,这些归一化系数被自动存储在xnorm.factors。对此数据集而言,TMM归一化的作用比较温和,这体现在所有的缩放因子都相对接近1。这种归一化的方法可以消除RNA组成所带来的误差。
(TMM方法文献:https://genomebiology.biomedcentral.com/articles/10.1186/gb-2010-11-3-r25)

标准化因子的生物学意义
其实这个标准化因子算法就是选出一个有代表性的gene X(其实是每个样本一个代表性gene X),而这个gene X的reads for gene X/average for gene X比值就是标准化因子。
只不过选取gene X的时候,通过对数变换和中位数的方法,更多的参考了中等表达基因和管家基因的数据趋势,而剔除了特异性表达基因和高差异表达基因的影响。
相比较RPKM,FPKM,TPM标准化方法是除以总Read数,DESeq2标准化方法是除以一个有代表性基因的Read数,只不过这个Read数进行了变换(它除以了几何平均Read数, reads for gene X/average for gene X)。因为更能处理存在特异性表达基因和高差异表达基因的数据。

通过得到calcNormFactors,我们可以得到有效库大小,从而得到消除了测序深度以及在某个样本中特异性表达基因(RNA组成)所带来的影响。

3.最终使用CPM值做接下来的分析。选取样本的中位值做分析。(中位值参考文献。)

4.R语言学习:tidyfst、reshape2包进行数据的长宽转换,dplyr包中的mutate、group_by函数进行列的计算、分组计算等。

整理为规范的SPM上游分析文件

#设置工作路径
setwd("D:/gtex")
#检查内存分配限制
memory.limit()
stringsAsFactors=FALSE
#设置为1G内存
memory.limit(1000000)
#初始化环境:
rm(list=ls())
#导入数据
vs <- read.table(file = "vs.tsv")
load(file = "step_2.Rdata")
#将基因名导入数据框中并用作行名,多个ensembl_id对应一个基因名就取其中一个
Var1 = as.character(melt_1$Var1)
melt_1 <- melt_1[,-1]
melt_1 <- data.frame(cbind(Var1,melt_1))
#tmp <- vs[vs[,1] %in% melt_1[,1],c(1:2)]
colnames(melt_1)[1] <- "Name"
#tmp_1 <- merge(tmp,melt_1,by = "Name")
tmp_1 <- merge(vs,melt_1,by = "Name")
length(unique(tmp_1[,2]))
library(dplyr)
tmp_2 <- distinct(tmp_1,Description,.keep_all = TRUE)
rownames(tmp_2) <-  tmp_2[,2]
exprset <- tmp_2[,-c(1:2)] 
#删除中间文件
rm(tmp,tmp_1,tmp_2)
colnames(exprset) <- c(
  "Adrenal_Gland",
  "Brain",
  "Breast",
  "Left_Ventricle",
  "Kidney",
  "Liver",
  "Lung",
  "Skeletal_Muscle",
  "Pancreas",
  "Skin",
  "Stomach",
  "Testis",
  "Uterus"
)

write.table(exprset,file = "exprset.txt",sep = '\t')
> dim(exprset)
[1] 36598    13

说明:如果多个ensembl name对应一个gene symbol,我们就只取其中的一个ensembl name进行后续的分析。这一步的基因数目从36692到36598,误差不大。
warning:这一步涉及到手动改列名,发现了一个错误,以后一定要多加小心,能不手动尽量不要手动。

你可能感兴趣的:(复盘总结(三))