#' Tally Positive Fluorescent Values
#'
#' Tally positive and negative values from from the data.frame generated
#' by \code{\link{parseImages}} by a grouping variable such as \code{"well"}
#' or \code{"file"} that corresponds to a single multiplicity.
#'
#' @param df Annotated \code{data.frame} with fluorescent values to evaluate.
#' @param pd Optional phenotype \code{data.frame} to add to results.
#' @param moi Character string identifying the independent value. If \code{NULL},
#' variables named \code{"moi"} and \code{"x"} will be sought. Note
#' that in the returned value, this variable will be named \code{"x"}.
#' @param by Character string identifying the grouping variable. If \code{NULL},
#' either \code{"well"} or \code{"file"} must be present and will be used as
#' the grouping variable.
#' @param param Character string identifying the variable in \code{df} to evaluate,
#' typically \code{"mfi"}.
#'
#' @details
#'
#' The variable named \code{positive} will be tallied for each value of
#' \code{moi} (if present) represented by each level of the grouping
#' variable \code{by}.
#'
#' @return
#'
#' A \code{data.frame} of tallied values for each level of the grouping
#' variable (typically \code{well} or \code{file}) with additional information
#' provided by the optional phenotype data. Variables generated by \code{\link{tally}} are
#' expected by downstream functions. Notably, the dependent variable will
#' be renamed \code{x} in the output. These variables include:
#' \itemize{
#' \item The independent variable representing the multiplicity of infection
#' in \code{x}
#' \item The dependent variable as the fraction of positive cells in \code{y}
#' \item The number of positive cells in \code{pos}
#' \item The number of negative in \code{neg}
#' \item Details about the grouping variable, typically \code{well} or \code{file}
#' }
#'
#' @examples
#' # Sample data by folder
#' f <- system.file("extdata", "by_folder", package = "virustiter")
#' pd <- read.csv(system.file("extdata", "by_folder/phenoData.csv", package = "virustiter"))
#' i <- getImages(f)
#' v <- parseImages(i)
#' v <- mergePdata(pd, v)
#' v <- score(v)
#' tally(v)
#'
#' @import
#' EBImage
#'
#' @export
#'
tally <- function(df, pd = NULL, moi = NULL, by = NULL, param = "mfi")
{
# parameter check
if(!"positive" %in% names(df))
stop("\ntally() requires the logical variable 'positive'.",
"\nPerhaps score() needs to be called on '", deparse(substitute(df)))
# if the moi is NULL, first seek "moi" and then "x" in df
if (is.null(moi)) {
moi <- FALSE
if ("moi" %in% names(df))
moi <- "moi"
else if ("x" %in% names(df))
moi <- "x"
else
message("No variable has been assigned to 'moi'")
}
else if (!moi %in% names(df))
stop("'", moi, "' is missing from ", deparse(substitute(df)))
# assign grouping value
if (!is.null(by) && !by %in% names(df))
stop("'", by, "' is missing from ", deparse(substitute(df)))
else if ("well" %in% names(df))
by <- "well"
else if ("file" %in% names(df))
by <- "file"
else
stop("Unable to use '", deparse(substitute(by)), "' as grouping variable")
group <- df[[by]]
# check for param
if (!param %in% names(df))
stop("'", param, "' is missing from ", deparse(substitute(df)))
# record unit of measure
unit <- df$unit[1]
if (is.null(unit))
unit <- "[no unit]"
# tally positive and create results data.frame
res <- aggregate(cbind(positive == TRUE, positive == FALSE) ~ group, df, sum)
names(res)[2:3] <- c("pos", "neg")
y <- with(res, pos/(pos + neg))
if (moi == FALSE)
x <- 1
else
x <- sapply(levels(res$group), function(v) df[[moi]][group == v][1])
if (by == "well") {
well <- levels(as.factor(res$group))
row <- well.info(well)$row
column <- well.info(well)$column
res <- cbind(well, row, column, unit, res[c("pos", "neg")], x, y)
}
else if (by == "file") {
file <- levels(as.factor(res$group))
res <- cbind(file, unit, res[c("pos", "neg")], x, y)
}
else {
group <- levels(as.factor(res$group))
res <- cbind(group, unit, res[c("pos", "neg")], x, y)
}
if (!is.null(pd)) {
n1 <- max(nchar(levels(as.factor(pd$well))))
n2 <- max(nchar(levels(as.factor(df$well))))
nmax <- max(n1, n2)
if (nmax <= 2)
formatString <- NULL
else
formatString <- sprintf("%%0%dd", nmax - 1)
res <- mergePdata(pd, res, formatString = formatString)
}
rownames(res) <- NULL
return(res)
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.