#' Plot the obtained null distribution along with a histogram of observed test
#' statistics
#' @param fit an object returned by the reconsi() (or testDAA()) function
#' @param lowColor,highColor The low and high ends of the colour scale
#' @param idNull indices of known null taxa
#' @param nResampleCurves The number of resampling null distributions to plot
#' @param hSize A double, the size of the line of the collapsed null estimate
#'
#' @return a ggplot2 plot object
#' @import ggplot2
#' @importFrom reshape2 melt
#' @importFrom stats density
#' @importFrom ks dkde
#' @export
#' @examples
#' p = 180; n = 50; B = 1e2
#' #Low number of resamples keeps computation time down
#' x = rep(c(0,1), each = n/2)
#' mat = cbind(
#' matrix(rnorm(n*p/10, mean = 5+x),n,p/10), #DA
#' matrix(rnorm(n*p*9/10, mean = 5),n,p*9/10) #Non DA
#' )
#' #Provide just the matrix and grouping factor, and test using the random null
#' fdrRes = reconsi(mat, x, B = B)
#' plotNull(fdrRes)
plotNull = function(fit, lowColor ="yellow", highColor ="blue",
idNull = NULL, nResampleCurves = length(fit$Weights),
hSize = 0.5){
with(fit, {
zSeq = seq(min(statObs), max(statObs), length.out = 1e3)
zValsDensPerm = if(resamAssumeNormal){
apply(PermDensFits, 2, function(Fit){
dnorm(zSeq, mean = Fit["mean"], sd = Fit["sd"])
})
} else {
vapply(PermDensFits, FUN.VALUE = zSeq, function(Fit){dkde(zSeq, Fit)})
}
colnames(zValsDensPerm) = paste0("b", seq_len(ncol(zValsDensPerm)))
idCurves = Weights >= sort(Weights, decreasing = TRUE)[nResampleCurves]
#The Curves to plot
df1 = data.frame(weight = Weights,
Curve = colnames(zValsDensPerm))[idCurves,]
df2 = data.frame(zValsDensPerm[,idCurves], zSeq = zSeq)
moltdf2 = melt(df2, id.vars = c("zSeq"), variable.name = "Curve",
value.name = "Density")
dfMerged = merge(moltdf2, df1, by = "Curve")
#Permutation densities
plot = ggplot(data = dfMerged, aes(x = zSeq, group = Curve, y = Density,
col = weight, alpha = weight)) +
geom_line(linetype = "dashed", size = 0.4) +
scale_colour_continuous(high = highColor,
low = lowColor, name = "Weights") +
scale_alpha_continuous(guide = FALSE, range = c(0.5,1)) +
xlab(if(zValues) "z-value" else "Test statistic") +
ylab("Density/Fdr") + theme_bw() + xlim(range(statObs))
#Histogram of observed z-values
plot = plot + geom_histogram(data = data.frame(statObs = statObs),
aes(x = statObs, y = ..density..),
inherit.aes = FALSE, bins = 50, alpha = 0.5,
fill = "mediumseagreen")
# Add density functions
g0 = if(assumeNormal) dnorm(zSeq, mean = fitAll["mean"], sd = fitAll["sd"]) else dkde(zSeq, fitAll)
gObs = dkde(zSeq, fitObs)
gObs[gObs<0] =.Machine$double.eps
lfdr = g0/gObs*p0
lfdr[lfdr>1] = 1
#Only show lfdr for observed z-values
lfdr[zSeq > (max(statObs)+0.1) | zSeq < (min(statObs)-0.1)] = NA
dfDens = data.frame("zSeq" = zSeq, "ResampleNull" = g0,
"StandardNormal" = dnorm(zSeq)*sum(g0)/sum(dnorm(zSeq)),
"fdr" = lfdr)
if(!is.null(idNull)){
#If null taxa known, add true normal density
nullZdens = estNormal(y = statObs[idNull])
dfDens$OracleNullDensity = dnorm(zSeq, mean = nullZdens["mean"],
sd = nullZdens["sd"])
}
dfDensMolt = melt(dfDens, id.vars = "zSeq", value.name = "density",
variable.name = "type")
plot = plot + geom_line(inherit.aes = FALSE, data = dfDensMolt,
aes(x = zSeq, y = density, group = type,
linetype = type, size = type)) +
scale_linetype_manual(name = "",
values = c("solid", "dashed", "dotdash", if(!is.null(idNull)) "twodash")) +
scale_size_manual(values = c(0.2, 0.4, 0.4, if(!is.null(idNull)) 0.3), guide = FALSE)
# Add red dots for Fdr estimates
dfFdr = data.frame(statObs = statObs, Fdr = Fdr)
plot = plot + geom_point(inherit.aes = FALSE, data = dfFdr,
aes(x = statObs, y = Fdr), col = "red", size = hSize)
return(plot)
})
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.