Robust火山图:一种含离群值的代谢组数据差异分析方法

简介: 代谢组学中差异代谢物的识别仍然是一个巨大的挑战,并在代谢组学数据分析中发挥着突出的作用。由于分析、实验和生物的模糊性,代谢组学数据集经常包含异常值,但目前可用的差异代谢物识别技术对异常值很敏感。作者这里提出了一种基于权重的具有稳健性火山图方法,助于从含有离群值的代谢组数据中更加准确鉴定差异代谢物。

63bb68e0e25718939bdbabaa13768de.png

作者将提出的方法与其它9种代谢组中常用的方法(包含t-test)进行比较,发现有较低的misclassification error rates(MERs)和较高的AUC,证明了该方法的优越性。

63897fa93d3bd864177e3b273ecbd37.png

MERs比较

a9ada0e3c8611d9e023115e62fc17fe.png

AUC比较

安装加载数据集

Github:https://github.com/nishithkumarpaul/Rvolcano

library(devtools)
install_github("nishithkumarpaul/Rvolcano")
library(Rvolcano)
data("DummyFullData")
dim(DummyFullData)
[1] 40 40

数据集由40行代谢物和40个样本组成,其中(癌症和健康组各20生物学重复)

4b7a79f8566639ba11fd5502e71cad8.png

计算foldchange

fcval <- foldChngCalc(DummyFullData,nSampG1 = 20,nSampG2 = 20)
head(fcval)
## 查看该函数
edit(foldChngCalc)
function (data, nSampG1, nSampG2) 
{
  g1fold <- apply((data[, 1:nSampG1]), 1, weightedMean)
  g2fold <- apply((data[, (nSampG1 + 1):(nSampG1 + nSampG2)]), 
    1, weightedMean)
  foldChange <- g2fold - g1fold
  return(foldChange)
}

我们查看下foldChngCalc该函数,可以看到主要是通过apply函数计算了weightedMean值,即加权平均数, 而不是我们常用的mean(算术平均数)。

算术平均数又称均值,是统计学中基本的平均指标,就是简单的把所有数加起来然后除以个数。

加权平均数即加权平均值,是将各数值乘以相应的权数,然后加总求和得到总体值,再除以总的单位数。

通过一个例子计算下,观察weightedMean函数和mean有啥区别,,我们创建一个正态分布的向量集x和一个含有较高离群值的向量集,分布计算一下结果。

> set.seed(123)
> x<-c(rnorm(200,3,1)) 
> x1<-c(rnorm(180,3,1),rnorm(20,60,3)) #contain 20 outliers#
> weightedMean(x)
[1] 2.957601
> mean(x)
[1] 2.99143
> weightedMean(x1)
[1] 3.062994
> mean(x1)
[1] 8.712792
## 查看该函数的计算方法
function (a, b = 0.2) 
{
  w <- NULL
  pw <- NULL
  for (i in 1:length(a)) {
    w[i] <- exp(-(b/2) * (mad(a)^-2) * (a[i] - median(a))^2)
    pw[i] <- w[i] * a[i]
  }
  tpw <- sum(pw)
  tw <- sum(w)
  wm <- tpw/tw
  dd <- c(tpw, tw, wm)
  return(wm)
}

结果发现,不含离群值时,加权与算术平均数都一样,而含有离群值时候,结果容易形成误差,算术平均数易受极端数据的影响,极端值的出现,会使平均数的真实性受到干扰,加权差异有助于在进行计算时考虑更多数据,以便获得最准确的结果。

计算Pvalue

使用p.valcalc函数进行差异分析,使用robust vesion的t-test获取p值,公式可以查看函数源码,用到了weightedVar加权方差

## 添加Pvalue
pval <- NULL
for (i in 1:dim(DummyFullData)[1]){
  pval[i] <- p.valcalc(DummyFullData[i,1:20],DummyFullData[i,21:40])
  }
  ##查看该源码
  edit(p.valcalc)
  function (x, y) 
{
  t.stat <- (weightedMean(x) - weightedMean(y))/sqrt(((length(x) - 
    1) * weightedVar(x) + (length(y) - 1) * weightedVar(y)) * 
    (1/(length(x) + length(y) - 2)) * ((1/length(x)) + 1/length(y)))
  pval <- 2 * pt(abs(t.stat), (length(x) + length(y) - 2), 
    lower.tail = FALSE)
  return(pval)
}

绘制火山图

log2foldchange和Pvalue都有了,直接使用RobVolPlot函数绘图

##Robust volcano plot
RobVolPlot(fcval,pval,cexcutoff = 0.7,cexlab = 0.8,
           main = 'Volcano Plot',
           xlab = 'log2fc',
           ylab = '-log(Pvalue)',
           plimit = 0.05,fclimit = 2)
edit(RobVolPlot)

a93b386b59ea9e442c8547941b5e8de.png

ggplot2绘图

已经得到了log2foldchange和Pvalue数据了,我们就可以自己拿着数据绘制图形了

library(ggrepel)
## 获取数据
result <- data.frame(log2foldchange = fcval,p_value = pval)
result$threshold = factor(ifelse(result$p_value < 0.05 & abs(result$log2foldchange) >= 1, 
                                 ifelse(result$log2foldchange>= 1 ,'Up','Down'),'NoSignificance'),
                                 levels=c('Up','Down','NoSignificance'))
##差异代谢物
re <- subset(result,p_value < 0.05)
ggplot(result,aes(log2foldchange, -log10(p_value)))+
  geom_point(aes(color = threshold), size = 5) +
  scale_colour_manual(values = c('#fb81f5', '#6868ed', 'gray40'), labels = c('Enriched metabolites', 'Depleted metabolites', 'No diff')) +
  # 添加x轴标签
  xlab(bquote(Log[2] ~ '(fold change)')) +
  # 添加y轴标签
  ylab(bquote(-Log[10] ~ italic('Pvalue')))+
  # 添加标签:
  geom_text_repel(data = re, aes(color = threshold,label = rownames(re)),max.overlaps = 20,
                  size = 4.8 ,fontface = "bold",arrow = arrow(length=unit(0.01, "npc")),force = 1, max.iter = 3e3,
                  box.padding = unit(0.6, 'lines'), segment.color = 'black', show.legend = FALSE)+
  theme_bw()+
  # 调整主题和图例位置:
  theme(panel.grid = element_blank(),
        legend.position = c(0.01,0.25),
        legend.justification = c(0,1)
  )+
 geom_hline(yintercept = -log10(0.05), linetype = "dashed", color = "grey",size = 1)+
 geom_vline(xintercept = c(-1.2,1.2), linetype = "dashed", color = "grey",size = 1)

16a85f70547ecbccad3fc01c4c3deee.png

参考资料

  1. https://bmcbioinformatics.biomedcentral.com/articles/10.1186/s12859-018-2117-2
  2. 如何计算加权方差:https://cn.ebrdbusinesslens.com/88-how-8599659-calculate-weighted-variancel-37590
相关文章
|
2月前
|
数据可视化
R语言生态学进化树推断物种分化历史:分类单元数与时间关系、支系图可视化
R语言生态学进化树推断物种分化历史:分类单元数与时间关系、支系图可视化
R语言生态学进化树推断物种分化历史:分类单元数与时间关系、支系图可视化
|
2月前
|
机器学习/深度学习 数据可视化
数据分享|R语言生存分析模型因果分析:非参数估计、IP加权风险模型、结构嵌套加速失效(AFT)模型分析流行病学随访研究数据
数据分享|R语言生存分析模型因果分析:非参数估计、IP加权风险模型、结构嵌套加速失效(AFT)模型分析流行病学随访研究数据
|
2月前
|
数据挖掘 C语言
R语言极值理论 EVT、POT超阈值、GARCH 模型分析股票指数VaR、条件CVaR:多元化投资组合预测风险测度分析
R语言极值理论 EVT、POT超阈值、GARCH 模型分析股票指数VaR、条件CVaR:多元化投资组合预测风险测度分析
|
2月前
Stata广义矩量法GMM面板向量自回归 VAR模型选择、估计、Granger因果检验分析投资、收入和消费数据
Stata广义矩量法GMM面板向量自回归 VAR模型选择、估计、Granger因果检验分析投资、收入和消费数据
|
2月前
|
算法 数据可视化 数据挖掘
r语言有限正态混合模型EM算法的分层聚类、分类和密度估计及可视化(上)
r语言有限正态混合模型EM算法的分层聚类、分类和密度估计及可视化
|
2月前
|
算法 数据可视化 前端开发
r语言有限正态混合模型EM算法的分层聚类、分类和密度估计及可视化(下)
r语言有限正态混合模型EM算法的分层聚类、分类和密度估计及可视化
|
2月前
R语言估计多元标记的潜过程混合效应模型(lcmm)分析心理测试的认知过程
R语言估计多元标记的潜过程混合效应模型(lcmm)分析心理测试的认知过程
|
11月前
|
算法
基于有序模式的度量对多变量时间序列进行非线性分析研究(Matlab代码实现)
基于有序模式的度量对多变量时间序列进行非线性分析研究(Matlab代码实现)
102 0
|
2月前
【SPSS】两独立样本的极端反应检验和两配对样本的非参数检验详细操作教程(附案例实战)
【SPSS】两独立样本的极端反应检验和两配对样本的非参数检验详细操作教程(附案例实战)
94 0
|
11月前
|
数据可视化 数据挖掘 Linux
转录组下游分析丨利用limma包进行差异表达分析,结果可视化绘制火山图和热图
转录组下游分析丨利用limma包进行差异表达分析,结果可视化绘制火山图和热图