### general wrapper
#' Benchmarking wrapper: Given a multiple testing method, convert it so that it takes
#' a simulation object (see simulation function) and a nominal level alpha
#' as inputs
#'
#' @param mt_method Multiple testing method (e.g. a function such as gbh or ddhf)
#' @param nbins Integer, number of equally sized bins into which to stratify hypotheses
#'
#' @return A new multiple testing function which has an
#' interface of the form f(sim_data_frame, alpha)
#' @examples
#' sim_df <- du_ttest_sim(20000,0.95, 1.5)
#' sim_df$group <- groups_by_filter(sim_df$filterstat, 20)
#' obj <- tst_gbh(sim_df$pvalue, sim_df$group, .1)
#' sum(rejected_hypotheses(obj))
#'
#' tst_gbh_continuous <- continuous_wrap(tst_gbh)
#' obj2 <- tst_gbh_continuous(sim_df, .1)
#' sum(rejected_hypotheses(obj2))
#'
#' @export
continuous_wrap <- function(mt_method, nbins=20){
print(attr(mt_method,"fdr_method"))
if (attr(mt_method, "testing covariate") == "simple"){
f <- function(sim, alpha){
mt_method(sim$pvalue, alpha)
}
attr(f, "fdr_method") <- attr(mt_method, "fdr_method")
} else if (attr(mt_method, "testing covariate") == "stratified"){
f <- function(sim, alpha){
groups <- groups_by_filter(sim$filterstat, nbins)
mt_method(sim$pvalue, groups, alpha)
}
attr(f, "fdr_method") <- paste(attr(mt_method, "fdr_method"), nbins, "bins")
} else if (attr(mt_method, "testing covariate") == "continuous"){
f <- function(sim, alpha){
mt_method(sim$pvalue, sim$filterstat, alpha)
}
attr(f, "fdr_method") <- attr(mt_method, "fdr_method")
} else {
stop("unknown covariate handling")
}
attr(f, "fdr_pars") <- attr(mt_method, "fdr_pars")
f
}
#' scott_fdrreg: Wrapper for FDR regression (https://github.com/jgscott/FDRreg)
#'
#'
#' @param unadj_p Numeric vector of unadjusted p-values.
#' @param filterstat Factor to which different hypotheses belong
#' @param alpha Significance level at which to apply method
#' @param df Degrees of freedom for B-slines
#' @param lambda Ridge regularization parameter
#'
#' @return FDRreg multiple testing object
#'
#' @references James G. Scott, Ryan C. Kelly, Matthew A. Smith, Pengcheng Zhou, and Robert E. Kass.
#' "False discovery rate regression: application to neural synchrony detection in primary visual cortex."
#' Journal of the American Statistical Association (2015).
#' @importFrom splines bs
#' @importFrom stats model.matrix qnorm
#' @importFrom utils packageVersion
scott_fdrreg <- function(unadj_p, filterstat, alpha, df=3, lambda=0.01){
# no automated way to choose function space over which we optimize
# so we just use bs(df=3) as done in their analysis
# also no automated way of choosing ridge regularization parameter
if (! packageVersion("FDRreg") %in% c("0.2.1","0.2")){
stop(paste("Benchmarks were run against version 0.2 of FDRreg",
"available on github via:",
"devtools::install_github(repo= 'jgscott/FDRreg', subdir='R_pkg/', ref = 'a63cebae6faecb1fb0ebee634195296f39faa11b')"
))
}
b <- bs(filterstat, df=df)
Xs <- model.matrix( ~ b - 1)
fdrreg_res <- FDRreg(qnorm(unadj_p), Xs, control=list(lambda = 0.01))
# modification to make this method applicable to p-values
# FDRreg tests in a two-sided way, this means that we might get rejections
# due to the right tail (high p-values) which have a z-score > 0 !
# for this reason, just set local-fdr to 1 or equivalently the posterior prob to 0
posterior_probs <- ifelse(unadj_p <= 0.5, fdrreg_res$postprob, 1)
FDR <- getFDR(fdrreg_res$postprob)$FDR
obj <- list(adj_p = FDR,
pi0_continuous = fdrreg_res$priorprob, pi0=fdrreg_res$p0,
method="FDRreg", alpha=alpha)
class(obj) <- "FDRreg"
obj
}
attr(scott_fdrreg, "testing covariate") <- "continuous"
attr(scott_fdrreg, "fdr_method") <- "FDRreg"
#' @importFrom IHW rejected_hypotheses
rejected_hypotheses.FDRreg <- function(object, alpha= object$alpha){
object$adj_p <= alpha
}
setOldClass("FDRreg")
setMethod("rejected_hypotheses", signature("FDRreg"), rejected_hypotheses.FDRreg)
#' ddhf: Greedy independent filtering
#'
#' @param unadj_p Numeric vector of unadjusted p-values.
#' @param filterstat Factor to which different hypotheses belong
#' @param alpha Significance level at which to apply method
#'
#' @return DDHF multiple testing object
#'
#' @examples
#' sim_df <- du_ttest_sim(20000,0.95, 1.5)
#' obj <- ddhf(sim_df$pvalue, sim_df$filterstat, .1)
#' sum(rejected_hypotheses(obj))
#'
#' @export
#' @importFrom Rcpp evalCpp
#' @importFrom Rcpp sourceCpp
#' @useDynLib IHWpaper, .registration=TRUE
ddhf <- function(unadj_p, filterstat, alpha){
sortedp <- sort(unadj_p)
ranksp <- rank(unadj_p, ties.method="first")
filterorder <- order(filterstat)
filterrank <- rank(filterstat)
sortedp_filterorder <- ranksp[filterorder]
rjs <- ddhf_order(sortedp, sortedp_filterorder, alpha)
j <- which.max(rjs)[1]
m <- length(unadj_p)
adj_p <- rep(1, m)
adj_p[filterrank >= j] <- p.adjust(unadj_p[filterrank >= j], method="BH")
ddhf_obj <- list(adj_p = adj_p, rejections = max(rjs),
cutoff_quantile=j/m,
cutoff_value = filterstat[filterorder][j],
alpha=alpha)
class(ddhf_obj) <- "DDHF"
ddhf_obj
}
attr(ddhf, "testing covariate") <- "continuous"
attr(ddhf, "fdr_method") <- "Greedy Indep. Filt."
# actually greedy independent filtering does not need continuous covariates,
# it is sufficient if covariates can be ordered!
rejected_hypotheses.DDHF <- function(object, alpha= object$alpha){
object$adj_p <= alpha
}
setOldClass("DDHF")
setMethod("rejected_hypotheses", signature("DDHF"), rejected_hypotheses.DDHF)
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.