2019-12-05(关于logfc和p值)

9:00-9:40

昨天在小郭老师讲述了关于logfc和p值的含义,差不多有点理解的框架。差异倍数(fold change),fold change翻译过来就是倍数变化。limma接受的输入参数就是一个表达矩阵,而且是log后的表达矩阵(以2为底)。

那么最后计算得到的logFC这一列的值,其实就是输入的表达矩阵中case一组的平均表达量减去control一组的平均表达量的值,那么就会有正负之分,代表了case相当于control组来说,该基因是上调还是下调。

假设A基因表达值为1,B表达值为3,那么B的表达就是A的3倍。一般我们都用count、TPM或FPKM来衡量基因表达水平,所以基因表达值肯定是非负数,那么fold change的取值就是(0, +∞)。为什么我们经常看到差异基因里负数代表下调、正数代表上调?因为我们用了log2 fold change。当expr(A) < expr(B)时,B对A的fold change就大于1,log2 fold change就大于0(见下图),B相对A就是上调;当expr(A) > expr(B)时,B对A的fold change就小于1,log2 fold change就小于0。通常为了防止取log2时产生NA,我们会给表达值加1(或者一个极小的数),也就是log2(B+1) - log2(A+1)。

为什么不直接用表达之差,差直接有正负啊?假设A表达为1,B表达为8,C表达为64;直接用差B相对A就上调了7,C就相对B上调了56;用log2 fold change,B相对A就上调了3,C相对B也只上调了3. 通过测序观察我们发现,不同基因在细胞里的表达差异非常巨大,所以直接用差显然不合适,用log2 fold change更能表示相对的变化趋势。

p值是在统计学的范畴假设检验首先必须要有假设,我们假设A和B的表达没有差异(H0,零假设),然后基于此假设,通过t test(以RT-PCR为例)算出我们观测到的A和B出现的概率,就得到了P-value,如果P-value<0.05,那么说明小概率事件出现了,我们应该拒绝零假设,即A和B的表达不一样,即有显著差异。

显著性只能说明我们的数据之间具有统计学上的显著性,要看上调下调必须回去看差异倍数。

10:00-11:50

回过头解决了一些关于火山图出现的问题,这是因为我没有之前基因表达量没有取log,导致坐标太大。[图片上传失败...(image-74d97e-1575537977972)]

13:00-17:00

下午还是对代码块进行注释,然后比较观察之前做的图有什么不对劲的 。

options(stringsAsFactors = F)
load(file = 'step1-output.Rdata')
# 每次都要检测数据
exp[1:4,1:4] 
table(group_list) #table函数,查看group_list中的分组个数
#通过为每个数据集绘制箱形图,比较数据集中的数据分布
boxplot(exp[1,]~group_list) #按照group_list分组画箱线图

bp=function(g){         #定义一个函数g,函数为{}里的内容
  library(ggpubr)
  df=data.frame(gene=g,stage=group_list)
  p <- ggboxplot(df, x = "stage", y = "gene",
                 color = "stage", palette = "jco",
                 add = "jitter")
  #  Add p-value
  p + stat_compare_means()
}
bp(exp[1,]) ## 调用上面定义好的函数,避免同样的绘图代码重复多次敲。
bp(exp[2,])
bp(exp[3,])
bp(exp[4,])
dim(exp)

library(limma)
design=model.matrix(~factor( group_list ))
fit=lmFit(exp,design)
fit=eBayes(fit)
## 上面是limma包用法的一种方式 
options(digits = 4) #设置全局的数字有效位数为4
#topTable(fit,coef=2,adjust='BH') 
topTable(fit,coef=2,adjust='BH') 
## 但是上面的用法做不到随心所欲的指定任意两组进行比较

design <- model.matrix(~0+factor(group_list))
colnames(design)=levels(factor(group_list))
head(design)
exprSet=exp
rownames(design)=colnames(exprSet)
design
contrast.matrix<-makeContrasts("Normal-ACC",
                               levels = design)
contrast.matrix ##这个矩阵声明,我们要把 Tumor 组跟 Normal 进行差异分析比较
colnames(design)
deg = function(exprSet,design,contrast.matrix){
  ##step1
  fit <- lmFit(exprSet,design)
  ##step2
  fit2 <- contrasts.fit(fit, contrast.matrix) 
  ##这一步很重要,大家可以自行看看效果
  
  fit2 <- eBayes(fit2)  ## default no trend !!!
  ##eBayes() with trend=TRUE
  ##step3
  tempOutput = topTable(fit2, coef=1, n=Inf)
  nrDEG = na.omit(tempOutput) 
  #write.csv(nrDEG2,"limma_notrend.results.csv",quote = F)
  head(nrDEG)
  return(nrDEG)
}

deg = deg(exprSet,design,contrast.matrix)

head(deg)

save(deg,file = 'deg.Rdata')

load(file = 'deg.Rdata')
head(deg)
bp(exp[rownames(deg)[1],])
## for volcano 
if(T){
  nrDEG=deg
  head(nrDEG)
  attach(nrDEG)
  plot(logFC,-log10(P.Value))
  library(ggpubr)
  df=nrDEG
  df$v= -log10(P.Value) #df新增加一列'v',值为-log10(P.Value)
  ggscatter(df, x = "logFC", y = "v",size=0.5)
  
  df$g=ifelse(df$P.Value>0.01,'stable', #if 判断:如果这一基因的P.Value>0.01,则为stable基因
              ifelse( df$logFC >1,'up', #接上句else 否则:接下来开始判断那些P.Value<0.01的基因,再if 判断:如果logFC >1.5,则为up(上调)基因
                      ifelse( df$logFC < -1,'down','stable') )#接上句else 否则:接下来开始判断那些logFC <1.5 的基因,再if 判断:如果logFC <1.5,则为down(下调)基因,否则为stable基因
  )
  table(df$g)
  df$name=rownames(df)
  head(df)
  ggscatter(df, x = "logFC", y = "v",size=0.5,color = 'g')
  ggscatter(df, x = "logFC", y = "v", color = "g",size = 0.5,
            label = "name", repel = T,
            #label.select = rownames(df)[df$g != 'stable'] ,
            label.select =head(rownames(deg)), #挑选一些基因在图中显示出来
            palette = c("#00AFBB", "#E7B800", "#FC4E07") )
  ggsave('volcano2.png')
  
  ggscatter(df, x = "AveExpr", y = "logFC",size = 0.2)
  df$p_c = ifelse(df$P.Value<0.001,'p<0.001',
                  ifelse(df$P.Value<0.01,'0.0010.01'))
  table(df$p_c )
  ggscatter(df,x = "AveExpr", y = "logFC", color = "p_c",size=0.2, 
            palette = c("green", "red", "black") )
  ggsave('MA.png')
  
  
}

## for heatmap 
if(T){ 
  load(file = 'step1-output.Rdata')
  # 每次都要检测数据
  dat[1:4,1:4]
  table(group_list)
  x=deg$logFC #deg取logFC这列并将其重新赋值给x
  names(x)=rownames(deg) #deg取probe_id这列,并将其作为名字给x
  cg=c(names(head(sort(x),100)),#对x进行从小到大排列,取前100及后100,并取其对应的探针名,作为向量赋值给cg
       names(tail(sort(x),100)))
  library(pheatmap)
  pheatmap(dat[cg,],show_colnames =F,show_rownames = F) #对dat按照cg取行,所得到的矩阵来画热图
  n=t(scale(t(dat[cg,])))#通过“scale”对log-ratio数值进行归一化,现在的dat是行名为探针,列名为样本名,由于scale这个函数应用在不同组数据间存在差异时,需要行名为样本,因此需要用t(dat[cg,])来转换,最后再转换回来
  
  n[n>2]=2
  n[n< -2]= -2
  n[1:4,1:4]
  pheatmap(n,show_colnames =F,show_rownames = F)
  ac=data.frame(g=group_list)
  rownames(ac)=colnames(n) #将ac的行名也就分组信息(是‘no TNBC’还是‘TNBC’)给到n的列名,即热图中位于上方的分组信息
  pheatmap(n,show_colnames =F,
           show_rownames = F,
          cluster_cols = T, 
           annotation_col=ac,filename = 'heatmap_top200_DEG.png') #列名注释信息为ac即分组信息
  
  
}

write.csv(deg,file = 'deg.csv')








你可能感兴趣的:(2019-12-05(关于logfc和p值))