#' Artificial Extinction
#'
#' Remove tokens that do not occur in a fossil "template" taxon from a living
#' taxon, to simulate the process of fossilization in removing data from
#' a phylogenetic dataset.
#'
#' Further details are provided in \insertCite{Asher2020;textual}{TreeTools}.
#'
#' Note: this simple implementation does not account for character contingency,
#' e.g. characters whose absence imposes inapplicable or absent tokens on
#' dependent characters.
#'
#' @param dataset Phylogenetic dataset of class `phyDat` or `matrix`.
#' @param subject Vector identifying subject taxa, by name or index.
#' @param template Character or integer identifying taxon to use as a template.
#' @param replaceAmbiguous,replaceCoded Character specifying whether tokens
#' that are ambiguous (`?`) or coded (not `?`) in the fossil template should
#' be replaced with:
#' - `original`: Their original value; i.e. no change;
#' - `ambiguous`: The ambiguous token, `?`;
#' - `binary`: The tokens `0` or `1`, with equal probability;
#' - `uniform`: One of the tokens present in `sampleFrom`, with equal
#' probability;
#' - `sample`: One of the tokens present in `sampleFrom`, sampled according
#' to their frequency.
#' @param replaceAll Logical: if `TRUE`, replace all tokens in a subject; if
#' `FALSE`, leave any ambiguous tokens (`?`) ambiguous.
#' @param sampleFrom Vector identifying a subset of characters from which to
#' sample replacement tokens.
#' If `NULL`, replacement tokens will be sampled from the initial states of
#' all taxa not used as a template (including the subjects).
#' @return A dataset with the same class as `dataset` in which entries that
#' are ambiguous in `template` are made ambiguous in `subject`.
#'
#' @references
#' \insertAllCited{}
#' @examples
#' set.seed(1)
#' dataset <- matrix(c(sample(0:2, 4 * 8, TRUE),
#' "0", "0", rep("?", 6)), nrow = 5,
#' dimnames = list(c(LETTERS[1:4], "FOSSIL"),
#' paste("char", 1:8)), byrow = TRUE)
#' artex <- ArtificialExtinction(dataset, c("A", "C"), "FOSSIL")
#' @template MRS
#' @export
ArtificialExtinction <- function(dataset, subject, template,
replaceAmbiguous = "ambig",
replaceCoded = "original",
replaceAll = TRUE,
sampleFrom = NULL) {
UseMethod("ArtificialExtinction")
}
#' @rdname ArtificialExtinction
#' @importFrom fastmatch %fin%
#' @export
ArtificialExtinction.matrix <- function(dataset, subject, template,
replaceAmbiguous = "ambig",
replaceCoded = "original",
replaceAll = TRUE,
sampleFrom = NULL) {
replacers <- c("original", "ambiguous", "binary", "uniform", "frequency")
replaceA <- pmatch(replaceAmbiguous, replacers)
if (is.na(replaceA)) stop("`replaceAmbiguous` ambiguously matched.")
replaceC <- pmatch(replaceCoded, replacers)
if (is.na(replaceC)) stop("`replaceCoded` ambiguously matched.")
removes <- dataset[template, ] == "?"
if (is.null(sampleFrom)) {
sampleFrom <-
if (is.numeric(template)) {
-template
} else {
rownames(dataset)[!rownames(dataset) %fin% template]
}
}
.DoReplace <- function(dataset, subject, columns, replace) {
nCols <- sum(columns)
replaceWith <- switch(replace,
dataset[subject, columns], # Original
"?", # Ambiguous
sample(c("0", "1"), nCols * length(subject), replace = TRUE), # Binary
apply(unique(dataset[sampleFrom, columns, drop = FALSE]), 2, sample,
length(subject), replace = TRUE), # Uniform
apply(dataset[sampleFrom, columns, drop = FALSE], 2, sample,
length(subject), replace = TRUE) # Frequency
)
# Until require R >= 3.5.0
isFALSE <- function(x) is.logical(x) && length(x) == 1L && !is.na(x) && !x
if (isFALSE(replaceAll)) {
replaceWith[dataset[subject, columns] == "?"] <- "?"
}
dataset[subject, columns] <- replaceWith
dataset
}
dataset <- .DoReplace(dataset, subject, removes, replaceA)
dataset <- .DoReplace(dataset, subject, !removes, replaceC)
dataset
}
#' @rdname ArtificialExtinction
#' @export
ArtificialExtinction.phyDat <- function(dataset, subject, template,
replaceAmbiguous = "ambig",
replaceCoded = "original",
replaceAll = TRUE,
sampleFrom = NULL) {
MatrixToPhyDat(ArtificialExtinction(PhyDatToMatrix(dataset), subject,
template,
replaceAmbiguous,
replaceCoded,
replaceAll,
sampleFrom))
}
#' @rdname ArtificialExtinction
#' @export
ArtEx <- ArtificialExtinction
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.