#' Creation of Fulfilled/Failed Constraint Counts.
#'
#' Creates counts of fullfilled/failed constraints.
#'
#' @param primer.df An evaluated \code{Primers} object.
#' @param eval.cols Evaluation columns in \code{primer.df} to consider.
#' By default (\code{NULL}) all evaluation columns are considered.
#' @return A data frame with the number of fulfilled/failed constraints
#' for \code{primer.df}.
#' @keywords internal
create_fulfilled_counts <- function(primer.df, eval.cols = NULL) {
# compute a data frame of passed/failed constraints
primer.df <- asS3(primer.df)
if (length(eval.cols) != 0) {
m <- match(eval.cols, colnames(primer.df))
na.idx <- which(is.na(m))
if (length(na.idx) != 0) {
msg <- paste("EVAL columns unknown: ",
paste(eval.cols, collapse = ","), sep = "")
warning(msg)
m <- m[-na.idx]
}
primer.df <- cbind("Run" = primer.df$Run, primer.df[,m, drop = FALSE])
}
constraint.idx <- grep("^EVAL_", colnames(primer.df))
if (length(constraint.idx) == 0) {
return(NULL)
}
constraint.names <- colnames(primer.df)[constraint.idx]
cols <- c("Run", constraint.names)
count.df <- ddply(primer.df[,cols], "Run",
catcolwise(sum))
# enrich with failures:
failure.df <- ddply(primer.df[,cols], "Run",
catcolwise(function(x) length(x) - sum(x)))
failure.names <- paste(constraint.names,"_failure", sep = "")
colnames(failure.df)[colnames(failure.df) %in% constraint.names] <-
failure.names
count.df <- cbind(count.df, failure.df)
return(count.df)
}
#' @rdname PrimerEval
#' @name PrimerEval
#' @aliases primer_significance
#' @details
#' \code{primer_significance} computes the significance by comparing
#' the total count of fulfilled and failed constraints
#' with the corresponding counts of primer sets from the literature.
#' Significant p-values indicate primer sets whose rate of constraint
#' fulfillment is higher compared to the reference sets.
#'
#' @return \code{primer_significance} returns a numeric providing
#' the p-value of the primer set according to Fisher's exact test.
#' The returned value has the following attributes:
#' \describe{
#' \item{\code{test}}{The results of the significance test}
#' \item{\code{tab}}{The confusion matrix for Fisher's exact test}
#' \item{\code{constraints}}{The names of the considered constraints}
#' }
#' @export
#' @examples
#'
#' # Determine the significance of a primer set
#' data(Ippolito)
#' p.data <- primer_significance(primer.df, "Ippolito")
#' attr(p.data,"tab") # the confusion matrix
#' attr(p.data, "test") # results from Fisher's test
#' attr(p.data, "constraints") # considered constraints for the test
primer_significance <- function(primer.df, set.name = NULL, active.constraints = NULL) {
if (length(primer.df) == 0 || nrow(primer.df) == 0) {
stop("Cannot compute significance for empty sets.")
}
if (is.null(set.name)) {
set.name <- primer.df$Run[1]
}
if (length(set.name) > 1) {
stop("Set name should have length 1.")
}
# evaluate counts of primer.df
eval.cols <- NULL
if (length(active.constraints) != 0) {
eval.cols <- paste0("EVAL_", active.constraints)
# select only available constraints
eval.cols <- eval.cols[eval.cols %in% colnames(primer.df)]
}
my.data <- create_fulfilled_counts(primer.df, eval.cols)
if (is.null(my.data)) { # no evaluated constraints
warning("Cannot compute a p-value since no constraints have been previously evaluated for the input primers.")
return(NULL)
}
# always exclude specificity and coverage as these are problem-specific
excl.cons <- c("EVAL_primer_specificity", "EVAL_primer_coverage")
excl.cons <- c(excl.cons, paste(excl.cons, "_failure", sep = ""))
constraint.names <- colnames(my.data)[grep("^EVAL_", colnames(my.data))]
constraint.names <- setdiff(constraint.names, excl.cons)
if (length(constraint.names) == 0) {
warning("No computed constraint of the provided primer set is suitable for determining set significance.")
# no constraints to be tested
return(NULL)
}
ok.names <- constraint.names[!grepl("_failure", constraint.names)]
failure.names <- constraint.names[grepl("_failure", constraint.names)]
# now, summarize across all constraints for a fisher's exact test
# -> Passed constraint count | Failed constraint count
my.ok <- unlist(apply(my.data[, ok.names, drop = FALSE], 1, function(x) sum(x, na.rm = TRUE)))
my.fail <- unlist(apply(my.data[, failure.names, drop = FALSE], 1, function(x) sum(x, na.rm = TRUE)))
# reference sysdata is available within the package automatically: REF.pass.counts, REF.fail.counts
m.ok <- match(constraint.names, names(REF.pass.counts))
m.fail <- match(constraint.names, names(REF.fail.counts))
ref.ok <- sum(unlist(REF.pass.counts[, m.ok[!is.na(m.ok)]]))
ref.fail <- sum(unlist(REF.fail.counts[, m.fail[!is.na(m.fail)]]))
# test primers:
tab <- matrix(c(my.ok, my.fail, ref.ok, ref.fail), nrow = 2,
ncol = 2,byrow = TRUE)
rownames(tab) <- c(set.name, "Reference")
colnames(tab) <- c("Fulfilled", "Failed")
# alternative: greater -> check only if odds ratio increases using the tested primers
# test primers should fulfill more constraints and have less failures
test.result <- fisher.test(tab, alternative = "greater")
out.constraint.names <- constraint.names[!grepl("_failure", constraint.names)]
out.constraint.names <- gsub("EVAL_", "", out.constraint.names)
result <- test.result$p.value
attr(result, "test") <- test.result
attr(result, "table") <- tab
attr(result, "constraints") <- out.constraint.names
return(result)
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.