#' Assert hla calls data frame format
#'
#' \code{checkHlaCallsFormat} asserts if hla calls data frame have proper
#' format.
#'
#' @param hla_calls HLA calls data frame, as returned by
#' \code{\link{readHlaCalls}} function.
#'
#' @return Logical indicating if \code{hla_calls} follows hla calls data frame
#' format. Otherwise raise an error.
#'
#' @importFrom assertthat assert_that see_if
#'
checkHlaCallsFormat <- function(hla_calls) {
an <- deparse(substitute(hla_calls))
assert_that(
is.data.frame(hla_calls),
see_if(nrow(hla_calls) >= 1 & ncol(hla_calls) >= 2,
msg = paste0(an, " have to have at least 1 rows and 2 columns.")
),
see_if(! any(vapply(hla_calls, is.factor, logical(length = 1))),
msg = paste0(an, " can't contain factors")
),
see_if(! all(checkAlleleFormat(as.character(hla_calls[, 1])), na.rm = TRUE),
msg = paste0("first column of ", an, " should specify samples id")
)
)
alleles <- unlist(hla_calls[, -1])
test_values <- checkAlleleFormat(alleles)
alleles <- alleles[! test_values & ! is.na(alleles)]
if (length(alleles) > 10) { alleles <- alleles[seq_len(10)] }
truncated <- ifelse(length(alleles) < 10, "", ", ...")
msg <- sprintf("values: %s%s in %s doesn't follow HLA numbers specification", paste(alleles, collapse = ", "), truncated, an)
assert_that(
all(test_values, na.rm = TRUE),
msg = msg
)
return(TRUE)
}
#' Assert KIR counts data frame format
#'
#' \code{checkKirCallsFormat} asserts if KIR counts data frame have proper
#' format.
#'
#' @param kir_calls KIR calls data frame, as returned by
#' \code{\link{readKirCalls}} function.
#'
#' @return Logical indicating if \code{kir_calls} follow KIR counts data frame
#' format. Otherwise raise an error.
#'
#' @importFrom assertthat assert_that see_if
#'
checkKirCallsFormat <- function(kir_calls) {
assert_that(
is.data.frame(kir_calls),
see_if(!any(vapply(
kir_calls, is.factor, logical(length = 1)
)),
msg = paste0(
"kir_calls can't contain factors"
)),
colnamesMatches(
kir_calls,
c("ID",
"KIR3DL3",
"KIR2DS2",
"KIR2DL2",
"KIR2DL3",
"KIR2DP1",
"KIR2DL1",
"KIR3DP1",
"KIR2DL4",
"KIR3DL1",
"KIR3DS1",
"KIR2DL5",
"KIR2DS3",
"KIR2DS5",
"KIR2DS4",
"KIR2DS1",
"KIR3DL2"
)
)
)
return(TRUE)
}
#' Check if frequencies can be calculated for an experiment
#'
#' \code{isExperimentCountsOrZeros} checks if experiment contains only positive
#' integers or zeros.
#'
#' @param x Matrix or SummarizedExperiment object.
#' @param na.rm Logical indicating if \code{NA} values should be accepted.
#'
#' @return Logical indicating if \code{x} contains only positive integers or
#' zeros.
#'
isExperimentCountsOrZeros <- function(x, na.rm = TRUE) {
test <- if (is.matrix(x)) {
isCountsOrZeros(x)
} else if (isClass(x, "SummarizedExperiment")) {
isCountsOrZeros(assay(x))
} else {
FALSE
}
return(test)
}
#' Assert statistical model
#'
#' \code{checkStatisticalModel} asserts if object is an existing fit from a
#' model functions such as lm, glm and many others. Containing MiDAS object as
#' its data atribute.
#'
#' @inheritParams updateModel
#'
#' @return Logical indicating if \code{object} is an existing fit from a
#' model functions such as lm, glm and many others. Containing MiDAS object as
#' its data attribute. Otherwise raise an error.
#'
#' @importFrom assertthat assert_that see_if
#' @importFrom rlang is_formula
#' @importFrom stats getCall
#'
checkStatisticalModel <- function(object) {
on <- deparse(substitute(object))
msg <- " was not recognized as a fit from a model function (such as lm, glm and many others)."
assert_that(
is.object(object),
msg = paste0(on, msg)
)
object_call <- getCall(object)
assert_that(
! is.null(object_call),
msg = paste0(on, msg, " ", on, " does not have 'call' attribute.")
)
# Preserve object environment; this is important because arguments are given
# in specific environment, but it is useful to be able to evaluate it in
# original context -- doh!
object_env <- attr(object$terms, ".Environment")
object_formula <- eval(object_call[["formula"]], envir = object_env)
assert_that(
is_formula(object_formula),
msg = paste0(on, msg, " ", on, " does not have 'formula' attribute.")
)
object_data <- eval(object_call[["data"]], envir = object_env)
assert_that(!is.null(object_data),
msg = paste0(on, msg, " ", on, " does not have 'data' attribute.")
)
return(TRUE)
}
#' Check if tidy method for class exist
#'
#' \code{hasTidyMethod} check if there is a tidy method available for a given class.
#'
#' @param class String giving object class.
#'
#' @return Logical indicating if there is a tidy method for a given class.
#'
#' @importFrom utils methods
#'
hasTidyMethod <- function(class) {
cl_fun <- paste0("tidy.", class)
test <- cl_fun %in% methods("tidy")
return(test)
}
assertthat::on_failure(hasTidyMethod) <- function(call, env) {
paste0("Could not find 'tidy' function for statistical model '",
eval(expr = call$class, envir = env),
"'. Please ensure that 'tidy' for selected model is available. See the 'broom' package for more information on 'tidy' function."
)
}
#' Check if vector contains only counts or zeros
#'
#' \code{isCountsOrZeros} checks if vector contains only positive integers or
#' zeros.
#'
#' @param x Numeric vector or object that can be \code{unlist} to numeric
#' vector.
#' @param na.rm Logical indicating if \code{NA} values should be accepted.
#'
#' @return Logical indicating if provided vector contains only positive integers
#' or zeros.
#'
#' @importFrom rlang is_integerish
#'
isCountsOrZeros <- function(x, na.rm = TRUE) {
x <- unlist(x)
test <- is_integerish(x) & x >= 0
test <- all(test, na.rm = na.rm)
return(test)
}
assertthat::on_failure(isCountsOrZeros) <- function(call, env) {
paste0("values in ", deparse(call$x), " are not counts (a positive integers) or zeros.")
}
#' Check if object is character vector or NULL
#'
#' \code{isCharacterOrNULL} checks if the object is a character vector or NULL.
#'
#' @param x object to test.
#'
#' @return Logical indicating if object is character vector or NULL
#'
isCharacterOrNULL <- function(x) {
test <- is.character(x) | is.null(x)
return(test)
}
assertthat::on_failure(isCharacterOrNULL) <- function(call, env) {
paste0(deparse(call$x), " is not a character vector or NULL.")
}
#' Check if object is number or NULL
#'
#' \code{isNumberOrNULL} checks if object is number (a length one numeric
#' vector) or NULL.
#'
#' @param x object to test.
#'
#' @return Logical indicating if object is number or NULL
#'
#' @importFrom assertthat is.number
#'
isNumberOrNULL <- function(x) {
test <- is.number(x) | is.null(x)
return(test)
}
assertthat::on_failure(isNumberOrNULL) <- function(call, env) {
paste0(deparse(call$x),
" is not a number (a length one numeric vector) or NULL."
)
}
#' Check if object is string or NULL
#'
#' \code{isStringOrNULL} checks if object is string (a length one character
#' vector) or NULL.
#'
#' @param x object to test.
#'
#' @return Logical indicating if object is string or NULL
#'
#' @importFrom assertthat is.string
#'
isStringOrNULL <- function(x) {
test <- is.string(x) | is.null(x)
return(test)
}
assertthat::on_failure(isStringOrNULL) <- function(call, env) {
paste0(deparse(call$x),
" is not a string (a length one character vector) or NULL."
)
}
#' Check if string matches one of possible values
#'
#' \code{stringMatches} checks if string is equal to one of the choices.
#'
#' @param x string to test.
#' @param choice Character vector with possible values for \code{x}.
#'
#' @return Logical indicating if \code{x} matches one of the strings in
#' \code{choice}.
#'
stringMatches <- function(x, choice) {
test <- x %in% choice
return(test)
}
assertthat::on_failure(stringMatches) <- function(call, env) {
paste0(deparse(call$x),
' should be one of "',
paste(eval(call$choice, envir = env), collapse = '", "'),
'".'
)
}
#' Check if object is flag or NULL
#'
#' \code{isFlagOrNULL} checks if object is flag (a length one logical vector) or
#' NULL.
#'
#' @param x object to test.
#'
#' @return Logical indicating if object is flag or NULL
#'
#' @importFrom assertthat is.flag
#'
isFlagOrNULL <- function(x) {
test <- (is.flag(x) && ! is.na(x)) || is.null(x)
return(test)
}
assertthat::on_failure(isFlagOrNULL) <- function(call, env) {
paste0(deparse(call$x),
" is not a flag (a length one logical vector) or NULL."
)
}
#' Check if character matches one of possible values
#'
#' \code{characterMatches} checks if all elements of a character vector matches
#' values in choices.
#'
#' @param x Character vector to test.
#' @param choice Character vector with possible values for \code{x}.
#'
#' @return Logical indicating if \code{x}'s elements matches any of the values
#' in \code{choice}.
#'
#' @importFrom assertthat assert_that
characterMatches <- function(x, choice) {
assert_that(is.character(x))
test <- if (length(x)) {
all(x %in% choice)
} else {
FALSE
}
return(test)
}
assertthat::on_failure(characterMatches) <- function(call, env) {
paste0(deparse(call$x),
' should match values "',
paste(eval(call$choice, envir = env), collapse = '", "'),
'".'
)
}
#' Check if object is of class x or null
#'
#' \code{isClassOrNULL} checks if object is an instance of a specified class or
#' is null.
#'
#' @param x object to test.
#' @param class String specifying class to test.
#'
#' @return Logical indicating if \code{x} is an instance of \code{class}.
#'
#' @importFrom assertthat assert_that
#' @importFrom methods is
#'
isClassOrNULL <- function(x, class) {
test <- is(x, class) | is.null(x)
return(test)
}
assertthat::on_failure(isClassOrNULL) <- function(call, env) {
paste0(deparse(call$x),
" must be an instance of ",
deparse(call$class),
" or NULL."
)
}
#' Check column names
#'
#' \code{colnamesMatches} check if data frame's columns are named as specified
#'
#' @param x Data frame to test.
#' @param cols Ordered character vector to test against \code{x}'s colnames.
#'
#' @return Logical indicating if \code{x}'s colnames equals \code{choice}.
#'
#' @importFrom assertthat assert_that
#'
colnamesMatches <- function(x, cols) {
assert_that(
is.data.frame(x),
see_if(ncol(x) == length(cols),
msg = sprintf(
"%s shiuld have %i columns: %s",
deparse(substitute(x)),
length(cols),
paste(cols, collapse = ", ")
)
)
)
columns_names <- colnames(x)
columns_test <- columns_names == cols
test <- all(columns_test)
return(test)
}
assertthat::on_failure(colnamesMatches) <- function(call, env) {
curr_colnames <- colnames(eval(call$x, envir = env))
future_colnames <- eval(call$cols, envir = env)
mask <- ! curr_colnames %in% future_colnames
sprintf("Columns: '%s' in %s should be named '%s'",
paste(curr_colnames[mask], collapse = "', '"),
deparse(call$x),
paste(future_colnames[mask], collapse = "', '")
)
}
#' Check if object is count or NULL
#'
#' \code{isCountOrNULL} check if object is a count (a single positive integer)
#' or NULL.
#'
#' @param x object to test.
#'
#' @return Logical indicating if object is count or NULL
#'
#' @importFrom assertthat is.count
#'
isCountOrNULL <- function(x) {
test <- is.count(x) | is.null(x)
return(test)
}
assertthat::on_failure(isCountOrNULL) <- function(call, env) {
paste0(deparse(call$x),
" is not a count (a single positive integer) or NULL."
)
}
#' Check if object is TRUE or FALSE flag
#'
#' \code{isTRUEorFALSE} check if object is a flag (a length one logical vector)
#' except NA.
#'
#' @param x object to test.
#'
#' @return Logical indicating if object is TRUE or FALSE flag
#'
#' @importFrom assertthat is.flag
#'
isTRUEorFALSE <- function(x) {
test <- is.flag(x) && ! is.na(x)
return(test)
}
assertthat::on_failure(isTRUEorFALSE) <- function(call, env) {
paste0(deparse(call$x),
" is not a flag (a length one logical vector)."
)
}
#' Check if placeholder is present in object formula
#'
#' \code{isTRUEorFALSE} check if object is a flag (a length one logical vector)
#' except NA.
#'
#' @param object statistical model to test.
#' @param placeholder string specifying name of placeholder.
#'
#' @return Logical indicating if placeholder is present in object formula.
#'
objectHasPlaceholder <- function(object, placeholder) {
object_env <- attr(object$terms, ".Environment")
object_call <- getCall(object)
object_form <- object_call[["formula"]] %>%
eval(envir = object_env)
test <- placeholder %in% all.vars(object_form)
return(test)
}
assertthat::on_failure(objectHasPlaceholder) <- function(call, env) {
paste0("placeholder '",
eval(call$placeholder, envir = env),
"' could not be found in object's formula"
)
}
#' Assert colData data
#'
#' \code{checkColDataFormat} asserts if the colData data frame has proper format.
#'
#' @param data_frame Data frame containing colData data used to construct
#' \code{\link{MiDAS}} object.
#'
#' @return Logical indicating if \code{data_frame} is properly formatted.
#' Otherwise raise an error.
#'
#' @importFrom assertthat assert_that see_if
#'
checkColDataFormat <- function(data_frame) {
data_frame_name <- deparse(substitute(data_frame))
assert_that(
see_if(
is.data.frame(data_frame),
msg = sprintf("%s have to be a data frame",
data_frame_name)
),
see_if(
nrow(data_frame) >= 1 & ncol(data_frame) >= 2,
msg = sprintf("%s have to have at least 1 row and 2 columns",
data_frame_name)
),
see_if(
colnames(data_frame)[1] == "ID",
msg = sprintf(
"first column in %s must be named 'ID'",
data_frame_name
)
)
)
return(TRUE)
}
#' Check if object is of class x
#'
#' \code{isClassOrNULL} checks if object is an instance of a specified class or
#' is null.
#'
#' @param x object to test.
#' @param class String specifying class to test.
#'
#' @return Logical indicating if \code{x} is an instance of \code{class}.
#'
#' @importFrom methods is
#'
isClass <- function(x, class) {
test <- is(x, class)
return(test)
}
assertthat::on_failure(isClass) <- function(call, env) {
paste0(deparse(call$x),
" must be an instance of ",
deparse(call$class),
"."
)
}
#' Validate frequency cutoffs
#'
#' \code{validateFrequencyCutoffs} checks if \code{lower_frequency_cutoff} and
#' \code{upper_frequency_cutoff} are valid.
#'
#' \code{lower_frequency_cutoff} and \code{upper_frequency_cutoff} should be a
#' positive numbers, giving either frequency or counts.
#' \code{lower_frequency_cutoff} has to be lower than
#' \code{upper_frequency_cutoff}.
#'
#' @param lower_frequency_cutoff Number
#' @param upper_frequency_cutoff Number
#'
#' @return Logical indicating if \code{lower_frequency_cutoff} and
#' \code{upper_frequency_cutoff} are valid.
#'
#' @importFrom assertthat assert_that see_if
#'
validateFrequencyCutoffs <- function(lower_frequency_cutoff, upper_frequency_cutoff) {
assert_that(
isNumberOrNULL(lower_frequency_cutoff),
if (! is.null(lower_frequency_cutoff)) {
see_if(lower_frequency_cutoff >= 0,
msg = "lower_frequency_cutoff must be a number greater than 0."
)
} else TRUE,
isNumberOrNULL(upper_frequency_cutoff),
if (! is.null(upper_frequency_cutoff)) {
see_if(upper_frequency_cutoff >= 0,
msg = "upper_frequency_cutoff must be a number greater than 0."
)
} else TRUE,
if (! is.null(lower_frequency_cutoff) && ! is.null(upper_frequency_cutoff)) {
see_if(! lower_frequency_cutoff > upper_frequency_cutoff,
msg = "lower_frequency_cutoff cannot be higher than upper_frequency_cutoff."
)
} else TRUE,
if (! is.null(lower_frequency_cutoff) && ! is.null(upper_frequency_cutoff)) {
see_if((lower_frequency_cutoff <= 1 && upper_frequency_cutoff <= 1) ||
(lower_frequency_cutoff >= 1 && upper_frequency_cutoff >= 1),
msg = "Both lower_frequency_cutoff and upper_frequency_cutoff have to be either frequencies or counts."
)
} else TRUE
)
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.