Nothing
#' @title Intergrative genes statistic
#' @description Calculate genes summary statistic across multiple datasets
#'
#' @param allGenes Vector of all genes names for the analysis.
#' @param dataList A list of expression matrices, in which rows are genes and columns are samples.
#' @param groupList A list of vectors indicating sample group corresponding with expression matrices in dataList.
#' @param ncores Number of core to use in prallel processing.
#' @param method Function for combining p-values. It must accept one input which is a vector of p-values and return a combined p-value. Three methods are embeded in this package are addCLT, fisherMethod, and stoufferMethod.
#'
#' @details
#'
#' To estimate the effect sizes of genes across all studies, first standardized mean difference
#' for each gene in individual studies is compute. Next, the overall efect size and standard error are estimated using
#' the random-efects model. This overall efect size represents the gene's expression change under the efect of
#' the condition. The, z-scores and p-values of observing such efect sizes are computed. The p-values is obtained
#' from classical hypothesis testing. By default, linear model and empirical Bayesian testing \(limma\) are used
#' to compute the p-values for diferential expression. The two-tailed p-values are converted to one-tailed p-values (lef- and right-tailed).
#' For each gene, the one-tailed p-values across all datasets are then combined using the addCLT, stouffer or fisher method.
#' These p-values represent how likely the diferential expression is observed by chance.
#'
#' @return A data.frame of gene statistics with following columns:
#'
#' \describe{
#' \item{pTwoTails}{Two-tailed p-values}
#' \item{pTwoTails.fdr}{Two-tailed p-values with false discovery rate correction}
#' \item{pLeft}{left-tailed p-values}
#' \item{pLeft.fdr}{left-tailed p-values with false discovery rate correction}
#' \item{pRight.fdr}{right-tailed p-values with false discovery rate correction}
#' \item{pRight}{right-tailed p-values}
#' \item{ES}{Effect size}
#' \item{ES.pTwoTails}{Two-tailed p-values for effect size}
#' \item{ES.pTwoTails.fdr}{Two-tailed p-values for effect size with false discovery rate correction}
#' \item{ES.pLeft}{Left-tailed p-values for effect size}
#' \item{ES.pLeft.fdr}{Left-tailed p-values for effect size with false discovery rate correction}
#' \item{ES.pRight}{Right-tailed p-values for effect size}
#' \item{ES.pRight.fdr}{Right-tailed p-values for effect size with false discovery rate correction}
#' }
#'
#' @author Tin Nguyen, Hung Nguyen, and Sorin Draghici
#'
#' @references
#'
#' Nguyen, T., Shafi, A., Nguyen, T. M., Schissler, A. G., & Draghici, S. (2020). NBIA: a network-based integrative analysis framework-applied to pathway analysis. Scientific reports, 10(1), 1-11.
#' Nguyen, T., Tagett, R., Donato, M., Mitrea, C., & Draghici, S. (2016). A novel bi-level meta-analysis approach: applied to biological pathway analysis. Bioinformatics, 32(3), 409-416.
#' Smyth, G. K. (2005). Limma: linear models for microarray data. In Bioinformatics and computational biology solutions using R and Bioconductor (pp. 397-420). Springer, New York, NY.
#'
#' @seealso \code{\link{addCLT}}
#'
#' @examples
#'
#' datasets <- c("GSE17054", "GSE57194", "GSE33223", "GSE42140")
#' data(list = datasets, package = "BLMA")
#' dataList <- lapply(datasets, function(dataset) {
#' get(paste0("data_", dataset))
#' })
#' groupList <- lapply(datasets, function(dataset) {
#' get(paste0("group_", dataset))
#' })
#' names(dataList) <- datasets
#' names(groupList) <- datasets
#'
#' allGenes <- Reduce(intersect, lapply(dataList, rownames))
#'
#' geneStat <- getStatistics(allGenes, dataList, groupList)
#' head(geneStat)
#'
#' # perform pathway analysis
#' library(ROntoTools)
#' # get gene network
#' kpg <- loadKEGGPathways()$kpg
#' # get gene network name
#' kpn <- loadKEGGPathways()$kpn
#' # get geneset
#' gslist <- lapply(kpg,function(y) nodes(y))
#'
#' # get differential expressed genes
#' DEGenes.Left <- rownames(geneStat)[geneStat$pLeft < 0.05 & geneStat$ES.pLeft < 0.05]
#' DEGenes.Right <- rownames(geneStat)[geneStat$pRight < 0.05 & geneStat$ES.pRight < 0.05]
#'
#' DEGenes <- union(DEGenes.Left, DEGenes.Right)
#'
#' # perform pathway analysis with ORA
#' oraRes <- lapply(gslist, function(gs){
#' pORACalc(geneSet = gs, DEGenes = DEGenes, measuredGenes = rownames(geneStat))
#' })
#' oraRes <- data.frame(p.value = unlist(oraRes), pathway = names(oraRes))
#' rownames(oraRes) <- kpn[rownames(oraRes)]
#'
#' # print results
#' print(head(oraRes))
#'
#' # perfrom pathway analysis with Pathway-Express from ROntoTools
#' ES <- geneStat[DEGenes, "ES"]
#' names(ES) <- DEGenes
#'
#' peRes = pe(x = ES, graphs = kpg, ref = allGenes, nboot = 1000, seed=1)
#'
#' peRes.Summary <- Summary(peRes, comb.pv.func = fisherMethod)
#' peRes.Summary[, ncol(peRes.Summary) + 1] <- rownames(peRes.Summary)
#' rownames(peRes.Summary) <- kpn[rownames(peRes.Summary)]
#' colnames(peRes.Summary)[ncol(peRes.Summary)] = "pathway"
#'
#' # print results
#' print(head(peRes.Summary))
#'
#' @import limma
#' @import metafor
#' @export
getStatistics <- function (allGenes, dataList, groupList, ncores = 1, method=addCLT) {
# calculate left and right p-values
pValue.Left <- pValue.Right <- data.frame(row.names=allGenes)
for (i in 1:length(dataList)){
dataset=names(dataList)[i]
data <- dataList[[i]]
group <- groupList[[i]]
data=data[rownames(data)%in%allGenes,]
gset=ExpressionSet(as.matrix(data))
fl <- as.factor(group)
gset$description <- fl
design <- model.matrix(~ description + 0, gset)
colnames(design) <- levels(fl)
fit <- lmFit(gset, design)
cont.matrix <- makeContrasts(d-c, levels=design)
fit2 <- contrasts.fit(fit, cont.matrix)
fit2 <- eBayes(fit2, 0.01)
tT <- topTable(fit2, adjust="fdr", sort.by="B", number=Inf)
tT$P.Left = ifelse(tT$logFC <0, tT$P.Value/2, 1-tT$P.Value/2)
tT$P.Right = ifelse(tT$logFC >0, tT$P.Value/2, 1-tT$P.Value/2)
pValue.Left[rownames(tT),dataset] <- tT[,"P.Left"]
pValue.Right[rownames(tT),dataset] <- tT[,"P.Right"]
}
pValue.Left$pAddCLT <- apply(pValue.Left[,1:length(dataList)], FUN = function(x) {method(na.omit(x))}, MARGIN = 1)
pValue.Right$pAddCLT <- apply(pValue.Right[,1:length(dataList)], FUN = function(x) {method(na.omit(x))}, MARGIN = 1)
controlSize <- controlMean <- controlStd <- data.frame(row.names=allGenes)
diseaseSize <- diseaseMean <- diseaseStd <- data.frame(row.names=allGenes)
for (i in 1:length(dataList)){
dataset=names(dataList)[i]
data <- dataList[[i]]
group <- groupList[[i]]
data=data[rownames(data)%in%allGenes,]
controlDat = data[,names(group)[group=="c"]]
diseaseDat = data[,names(group)[group=="d"]]
controlSize[rownames(controlDat), dataset] <- ncol(controlDat)
diseaseSize[rownames(diseaseDat), dataset] <- ncol(diseaseDat)
controlMean[rownames(controlDat), dataset] <- apply(controlDat, FUN=mean, MARGIN = 1)
diseaseMean[rownames(diseaseDat), dataset] <- apply(diseaseDat, FUN=mean, MARGIN = 1)
controlStd[rownames(controlDat), dataset] <- apply(controlDat, FUN=sd, MARGIN = 1)
diseaseStd[rownames(diseaseDat), dataset] <- apply(diseaseDat, FUN=sd, MARGIN = 1)
}
fc=mclapply(allGenes, FUN=calculateFC,
controlSize=controlSize, controlMean=controlMean, controlStd=controlStd,
diseaseSize=diseaseSize, diseaseMean=diseaseMean, diseaseStd=diseaseStd,
mc.cores=ncores)
names(fc) <- allGenes
effectSizes <- unlist(lapply(fc,FUN=function(x){x$beta}))
pValues <- unlist(lapply(fc,FUN=function(x){x$pval}))
mRNAStats = data.frame(row.names = allGenes, pLeft=pValue.Left[allGenes,]$pAddCLT,
pRight=pValue.Right[allGenes,]$pAddCLT,
ES=effectSizes[allGenes], ES.pTwoTails=pValues[allGenes])
mRNAStats$pTwoTails=2*apply(mRNAStats[,c("pLeft","pRight")], FUN=min, MARGIN = 1)
mRNAStats$ES.pLeft = ifelse(mRNAStats$ES <0, mRNAStats$ES.pTwoTails/2, 1-mRNAStats$ES.pTwoTails/2)
mRNAStats$ES.pRight = ifelse(mRNAStats$ES >0, mRNAStats$ES.pTwoTails/2, 1-mRNAStats$ES.pTwoTails/2)
mRNAStats$pLeft.fdr=p.adjust(mRNAStats$pLeft,method="fdr")
mRNAStats$pRight.fdr=p.adjust(mRNAStats$pRight,method="fdr")
mRNAStats$pTwoTails.fdr=p.adjust(mRNAStats$pTwoTails,method="fdr")
mRNAStats$ES.pLeft.fdr=p.adjust(mRNAStats$ES.pLeft,method="fdr")
mRNAStats$ES.pRight.fdr=p.adjust(mRNAStats$ES.pRight,method="fdr")
mRNAStats$ES.pTwoTails.fdr=p.adjust(mRNAStats$ES.pTwoTails,method="fdr")
mRNAStats
}
getSimilarityFromGrouping <- function(g) {
N=length(g)
S=matrix(0,N,N)
colnames(S)=rownames(S)=names(g)
for (j in unique(g)){
X=rep(0,N);
X[which(g==j)]=1
S=S+X%*%t(X)
}
S
}
hierClustering <- function(data, method=km, minSize=40) {
group <- rep(1, nrow(data));names(group) <- rownames(data)
elements <- rownames(data)
myGap <- clusGap(data[elements,],FUNcluster=method, K.max=2, B=50)
split= length(elements)>minSize & maxSE(myGap$Tab[,"gap"], myGap$Tab[,"SE.sim"], method="globalSEmax")>1
while (split==TRUE) {
g <- method(data[elements,], 2)$cluster + max(group)
group[elements] <- g
split <- FALSE
for (i in sort(unique(group))) {
elements = names(group)[which(group==i)]
if (length(elements)>minSize) {
myGap <- clusGap(data[elements,],FUNcluster=method, K.max=2, B=50)
if (maxSE(myGap$Tab[,"gap"], myGap$Tab[,"SE.sim"], method="globalSEmax")>1) {
split <- TRUE
break
}
}
}
}
group <- as.numeric(as.factor(group))
names(group) <- rownames(data)
group
}
getCommonGenes <- function(dataList, minGeneCount=3) {
allGenes=NULL
for (i in 1:length(dataList)) {
data <- dataList[[i]]
allGenes=union(allGenes, rownames(data))
}
dsCounts <- rep(0, length(allGenes))
names(dsCounts) <- allGenes
for (i in 1:length(dataList)) {
data <- dataList[[i]]
dsCounts[rownames(data)] <- dsCounts[rownames(data)] +1
}
allGenes <- names(dsCounts)[dsCounts>=minGeneCount]
allGenes
}
pORACalc=function(DEGeneNames,measuredGenes,geneSet,minSize) {
universe=measuredGenes
white=DEGeneNames
black=setdiff(measuredGenes,DEGeneNames)
sample=intersect(measuredGenes,geneSet)
sampleWhite=intersect(sample,DEGeneNames)
if (length(sampleWhite)<minSize) {res=NA}
else {
res=phyper(q=length(sampleWhite)-1,m=length(white),n=length(black),k=length(sample), lower.tail=FALSE)
}
res
}
calculateFC = function(gInd, controlSize, controlMean, controlStd, diseaseSize, diseaseMean, diseaseStd) {
# get dataset names without NA
ds=controlSize[gInd,]
ds=names(ds)[!is.na(ds)]
tmp=data.frame(Study=seq(length(ds)),Source=ds,
n1i=as.numeric(diseaseSize[gInd,ds]), m1i=as.numeric(diseaseMean[gInd,ds]), sd1i=as.numeric(diseaseStd[gInd,ds]),
n2i=as.numeric(controlSize[gInd,ds]), m2i=as.numeric(controlMean[gInd,ds]), sd2i=as.numeric(controlStd[gInd,ds]))
tmp1=escalc(measure="SMD", m1i=m1i, sd1i=sd1i, n1i=n1i,m2i=m2i, sd2i=sd2i, n2i=n2i, data=tmp)
res <- try(rma.uni(yi, vi, data=tmp1, control=list(stepadj=0.5,maxiter=10000), method="REML"),silent=TRUE)
res
}
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.