################
# Generate procedures for creating internal Rdata here.
# o Computes the reference distribution for Fisher's exact test on the number of
# fulfilled constraints
#################
#' Creation of Reference Data for Significance Tests
#'
#' Creates reference data for significance test on the ratio of
#' fulfilled constraints.
#'
#' @param set.name Primer set to exclude from the data.
#' @param top.k Select only the top k coverage sets for every locus.
#' If \code{top.k} is \code{NULL}, all primer sets
#' are selected to form the reference distribution.
#' @param settings Settings for evaluating constraints that are not part of the original data.
#' @keywords internal
sig_eval_ref_data <- function(set.name = "openPrimeR2017", top.k = NULL, settings) {
# load comparison data as reference frequencies
# other options: kolmogorov smirnov (compare 2 distributions)
# F-test to compare two variances (mine should be more narrow -> close to the target)
comp.loc <- system.file("extdata", "IMGT_data", "comparison", "primer_sets",
package = "openPrimeR")
comp.folders <- list.dirs(comp.loc, full.names = TRUE, recursive = FALSE)
comp.loc.t <- list.files(
system.file("extdata", "IMGT_data", "comparison",
"templates",package = "openPrimeR"),
full.names = TRUE)
count.data <- NULL
template.data <- read_templates(comp.loc.t)
for (i in seq_along(comp.folders)) { # for each Ig group (IGHV etc)
primer.set.location <- comp.folders[i]
primer.files <- list.files(path = primer.set.location, pattern = ".csv", full.names = TRUE)
primer.data <- read_primers(primer.files)
# add melting_temp_diff column here
# TODO: use settings here?
primer.data <- lapply(primer.data, function(x) cbind(x, "EVAL_melting_temp_diff" = x$melting_temp_diff < constraints(settings)$melting_temp_diff))
template.df <- template.data[[i]]
locus <- template.df$Run[1]
cvg <- sapply(primer.data, function(x) get_cvg_ratio(x, template.df))
# select reference set for this locus:
if (!is.null(top.k)) {
# selet top-k coverage sets
o <- order(cvg, decreasing = TRUE)
ref.sets <- primer.data[o[1:top.k]]
if (set.name %in% names(ref.sets)) {
# need another reference to have k sets (will remove `set.name` later
ref.sets <- primer.data[o[1:(top.k+1)]]
}
} else {
# select all cvg sets
ref.sets <- primer.data
}
# count number of fulfilled constraints of all other sets
# construct count data
ref.df <- asS3(do.call(my_rbind, ref.sets))
count.df <- create_fulfilled_counts(ref.df)
count.df <- cbind(Locus = locus, count.df)
count.data <- my_rbind(count.data, count.df)
}
# exclude my set from ref.sets
ref.data <- count.data[count.data$Run != set.name,]
# summarize across all primer sets
ref.data <- plyr::numcolwise(function(x) sum(x, na.rm = TRUE))(ref.data)
return(ref.data)
}
generate.country.dists <- function() {
# compute distances between countries for determining the fastest mirror for custom install scripts of the package
library(cshapes)
library(countrycode)
dmat <- distmatrix(as.Date("2002-1-1"), type = "capdist", useGW = FALSE) # correlates of war
my.names <- tolower(countrycode(rownames(dmat), "cown", "iso2c")) # turn countries to iso with 2 character encoding as used by R
country.dists <- dmat
colnames(country.dists) <- my.names
rownames(country.dists) <- my.names
return(country.dists)
}
#' Explore the properties of different coverage distribtuions.
#' @param template.df List with templates.
#' @param primer.data List with primers.
#' @param k Length of primers.
#' @return Does not return anything but performs exploration.
#' @keywords internal
explore.dists <- function(template.data, k = 18) {
# library(logspline)
for (i in seq_along(template.data)) {
template.df <- template.data[[i]]
sample <- names(template.data)[i]
print(sample)
cvg.df <- estimate.cvg(template.df, k = 18, "both", sample = sample)
x <- c(cvg.df$fw$Coverage_Ratio, cvg.df$rev$Coverage_Ratio)
png(paste0(sample, "_fit_discovery.png"))
descdist(x, discrete = FALSE)
dev.off()
fit.beta <- fitdist(x, "beta") # beta has high error
print(fit.beta)
fit.gamma <- fitdist(x, "gamma")
print(fit.gamma)
png(paste0(sample, "_gamma_fit.png"))
plot(fit.gamma)
dev.off()
png(paste0(sample, "_beta_fit.png"))
plot(fit.beta)
dev.off()
}
}
plot.ref.dists <- function() {
library(distrEx)
ref.dist <- list("plain(Easily~Feasible):~beta(1,10)" = Beta(1, 10),
"plain(Feasible):~beta(0.8,20)" = Beta(0.8, 20),
"plain(Hardly~Feasible):~beta(0.6,40)" = Beta(0.60, 40),
"plain(Unfeasible):~beta(0.3,200)" = Beta(0.3, 200))
results <- vector("list", length(ref.dist))
distribution_rep <- list()
for (i in seq_along(ref.dist)) {
dist <- ref.dist[[i]]
p1 <- dist@param@shape1
p2 <- dist@param@shape2
s <- rbeta(10000, shape1 = p1, shape2 = p2)
res <- data.frame("Distribution" = factor(names(ref.dist)[i]),
"x" = s)
results[[i]] <- res
distribution_rep[[names(ref.dist)[i]]] <- expression(beta(p1, p2))
}
df <- do.call(rbind, results)
library(ggplot2)
ggplot(df) + geom_histogram(aes(x = x)) + facet_wrap(~Distribution,
labeller = label_parsed) +
#Distribution = distribution_rep)) +
labs(x = "Coverage Ratio", y = "Number of Samples") +
scale_x_continuous(labels=scales::percent)
ggsave("beta_distribution.pdf")
}
#' Creation of Reference Coverage Ratio Distributions.
#'
#' Creates reference coverage ratio distributions in order to classify
#' primer design problems into three categories: easy, medium, and hard.
#'
#' @return A list with three reference beta distributions of coverage ratios.
#' @keywords internal
create.ref.dists <- function() {
#library(fitdistrplus)
library(distrEx)
# reference dists were determined empirically
# using the commented code from explore.dists() to determine good fits
###################
#data(Ippolito)
#template.data <- list("HCV" = read_templates("data/HCV/target_seqs.fasta"),
#"IGH" = template.df)
#explore.dists(template.data, k = 18)
#x.easy <- hist(rbeta(10000, shape1 = 0.9, shape2 = 15))
#x.medium <- hist(rbeta(10000, shape1 = 0.60, shape2 = 40))
# we made the hard distribution a bit like a normal distribution
# since in this case the parameter estimation may not give the
# actual distribution of the data. this is only the case for hard problems
# where the space of possible coverage ratios is tight.
#x.hard.before <- hist(rbeta(10000, shape1 = 0.3, shape2 = 200))
#x.hard <- hist(rbeta(10000, shape1 = 2, shape2 = 1000))
#x.HCV <- rbeta(10000, shape1 = 9.96, shape2 = 1606)
#x.IGH <- rbeta(10000, shape1 = 0.798, shape2 = 23.825)
#hist(x.easy)
#hist(x.medium)
#hist(x.hard)
#hist(x.HCV)
#hist(x.IGH)
#KL.matrix <- cbind(Easy = ref.dist$easy, Medium = ref.dist$medium, Hard = ref.dist$hard, TestVeryEasy = Beta(0.8, 10), TestEasy = Beta(0.7, 30), TestMedium = Beta(1, 100), TestHard = Beta(0.3, 1000))
#combis <- expand.grid(seq_len(ncol(KL.matrix)), seq_len(ncol(KL.matrix)))
#dist <- matrix(rep(NA, nrow(combis)), nrow = ncol(KL.matrix))
#colnames(dist) <- colnames(KL.matrix)
#rownames(dist) <- colnames(KL.matrix)
#for (i in 1:nrow(combis)) {
#x <- combis[i,1]
#y <- combis[i,2]
#dist[x,y] <- TotalVarDist(KL.matrix[1,x][[1]], unlist(KL.matrix[1,y][[1]]))
#}
# store three reference distributions
ref.dist <- list("very_easy" = Beta(1, 10),
"easy" = Beta(0.8, 20),
"medium" = Beta(0.60, 40),
"hard" = Beta(0.3, 200),
"very_hard" = Beta(10, 1000))
return(ref.dist)
}
get_model_formula <- function() {
# formula used for creating coverage model
return(Experimental_Coverage ~ annealing_DeltaG + Position_3terminusLocal + annealing_DeltaG * Position_3terminusLocal)
}
get.train.idx <- function(feature.matrix) {
# sample from training set to keep the data more balanced
deltaG.cuts <- -c(0, 5, 9, 13, Inf)
strat <- cut(feature.matrix$annealing_DeltaG, deltaG.cuts)
strat.types <- unique(strat)
strat.counts <- sapply(strat.types, function(x) length(which(x == strat)))
set.seed(1)
n.samples <- min(strat.counts)
# controlling for equal distribution of "Run": from 300 (equal distribution of DeltaG) to 168 samples
train.idx <- vector("list", length(strat.types))
set.seed(1)
for (i in seq_along(strat.types)) {
s <- strat.types[i]
idx <- which(strat == s)
cur.runs <- feature.matrix$Run[idx]
# select from each run randomly:
run.dist <- table(cur.runs)
run.sample.size <- min(run.dist, n.samples/2)
run.ids <- names(run.dist)
sel <- unlist(lapply(run.ids, function(x) sample(idx[which(feature.matrix$Run[idx] == x)], run.sample.size)))
#sel <- sapply(sample(idx, n.samples)
train.idx[[i]] <- sel
}
train.idx <- unlist(train.idx)
return(train.idx)
}
create.cvg.model <- function(feature.matrix) {
# create model for predicting coverage
#train.idx <- get.train.idx(feature.matrix) # remove bias from training data
cvg.model <- glm(get_model_formula(), family = "binomial", data = feature.matrix) #[train.idx,])
return(cvg.model)
}
create.FPR.table <- function(feature.matrix) {
# perform 10 repeats of 5-fold cross-validation using logistic regression models
library(caret)
library(e1071)
#train.idx <- get.train.idx(feature.matrix)
ctrl <- trainControl(method = "repeatedcv", number = 5, repeats = 10, savePredictions = TRUE, classProbs = TRUE)
model <- train(get_model_formula(), data = feature.matrix, method = "glm",
family="binomial", trControl = ctrl, tuneLength = 5) #, subset = train.idx)
# retrieve all fold-predictions (coverage probabilities) across all repetitions
cutoffs <- seq(0, 1, 0.0001)
n.pos <- length(which(model$pred$obs == "Amplified"))
n.neg <- length(which(model$pred$obs == "Unamplified"))
FPR.data <- lapply(cutoffs, function(x) {
#print(x)
cut.pred <- factor(ifelse(model$pred$Amplified > x, "Amplified", "Unamplified"), levels = c("Unamplified", "Amplified"))
tpr <- length(which(model$pred$obs == "Amplified" & cut.pred == "Amplified")) / n.pos
fpr <- length(which(model$pred$obs == "Unamplified" & cut.pred == "Amplified")) / n.neg
data.frame(Cutoff = x, FPR = fpr, TPR = tpr)
})
FPR.df <- do.call(rbind, FPR.data)
# verify:
print(FPR.df[500,])
return(FPR.df)
}
#########
# generate p-value ref data
#######
# use default settings for evaluating melting temp diff:
filename <- system.file("extdata", "settings",
"C_Taq_PCR_high_stringency.xml", package = "openPrimeR")
settings <- read_settings(filename)
ref.data <- sig_eval_ref_data(settings = settings)
REF.pass.counts <- ref.data[, !grepl("failure", colnames(ref.data))]
REF.fail.counts <- ref.data[, grepl("failure", colnames(ref.data))]
colnames(REF.fail.counts) <- gsub("_failure", "", colnames(REF.fail.counts))
###
# generate common restriction site Rdata
####
# seqRFLP data from REBASE:
# pkg: seqRFLP (>= 1.0.1)
utils::data("enzdata", package = "seqRFLP")
# common restriction enzymes retrieved from:
# https://www.addgene.org/mol-bio-reference/restriction-enzymes/
# annotate common sites in enzdata
common.file <- system.file("data-raw", "common_restriction_sites.txt", package = "openPrimeR")
common.sites <- as.character(read.table(common.file)[,1])
m <- match(common.sites, enzdata$nam)
enzdata$common <- FALSE
enzdata$common[m[!is.na(m)]] <- TRUE
# re-format search strings
# apostrophe -> indicates the sense cutting position,
# e.g. G_ACGT'C indicates a cut into ...GACGT and C...
# underscore -> indicates the antisense cutting position,
# e.g. G_ACGT'C indicates a cut into ...G and ACGTC....
enzdata$rep <- toupper(
gsub("_", "",
gsub("'", "", enzdata$site, fixed=TRUE),
fixed = TRUE))
####
# design problem classification -> coverage distribution references
####
cvg.ref.dists <- create.ref.dists()
#######
# build supervised model for predicting primer coverage:
#######
data(RefCoverage) # load ref.data and feature.matrix
CVG_MODEL <- create.cvg.model(feature.matrix)
FPR_TABLE <- create.FPR.table(feature.matrix)
########
# create country dists for install helper function for the shiny app
########
###############
# not part of sysdata:
#country.dists <- generate.country.dists() # selection of CRAN mirrors using closest distance to countries
# store country dists to extdata as shiny app isn't exactly in the package (cannot access sysdata)
#save(country.dists, file = file.path(system.file("extdata", package = "openPrimeR"), "country_dists.Rdata"))
###################################
############
# store sysdata
##########
devtools::use_data(REF.pass.counts, # p-value: pass counts for constraint fulfillment
REF.fail.counts, # p-value: fail counts for constraint fulfillment
cvg.ref.dists, # reference coverage distributions (problem difficulty estimation)
enzdata, # enzyme restriction sites
CVG_MODEL, # logistic model for predicting coveragee
FPR_TABLE, # conversion table from coverage-probabililties to FPR
internal = TRUE,
overwrite = TRUE) #, pkg = "openPrimeR")
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.