Nothing
#' Write the CharAnalysis results matrix to a CSV file
#'
#' Writes the \eqn{N \times 33} \code{char_results} matrix (assembled by
#' [char_post_process()]) to a CSV file whose column headers and numeric
#' format match the MATLAB CharAnalysis v2.0 \code{*_charResults.csv} output
#' exactly.
#'
#' @param char_results Numeric matrix (\eqn{N \times 33}) returned in
#' \code{out$char_results} by [CharAnalysis()].
#' @param site Character string: site name, used to build the
#' output filename (\code{<site>_charResults.csv}).
#' @param out_dir Directory in which to create the file. Required;
#' no default. Created if it does not exist. Use \code{tempdir()} for
#' a transient location, or supply a path of your choosing.
#' @param digits Number of significant digits for numeric output.
#' Default 7, matching MATLAB's \code{fprintf} default precision.
#' Use \code{NULL} for R's full double precision (15 digits).
#'
#' @return Invisibly returns the full path to the file written.
#'
#' @details
#' ## Column order and headers
#' Columns follow the MATLAB \code{charResults} layout:
#' \enumerate{
#' \item cm Top_i (cm)
#' \item age Top_i (yr BP)
#' \item char Count_i (#)
#' \item char Vol_i (cm3)
#' \item char Con_i (# cm-3)
#' \item char Acc_i (# cm-2 yr-1)
#' \item charBkg (# cm-2 yr-1)
#' \item char Peak (# cm-2 yr-1)
#' \item thresh 1 (# cm-2 yr-1)
#' \item thresh 2 (# cm-2 yr-1)
#' \item thresh 3 (# cm-2 yr-1)
#' \item thresh FinalPos (# cm-2 yr-1)
#' \item thresh FinalNeg (# cm-2 yr-1)
#' \item SNI (index)
#' \item thresh GOF (p-val)
#' \item peaks 1
#' \item peaks 2
#' \item peaks 3
#' \item peaks Final
#' \item peaks Insig.
#' \item peak Mag (# cm-2 peak-1)
#' \item smPeak Frequ (peaks 1ka-1)
#' \item smFRIs (yr fire-1)
#' \item nFRIs (#)
#' \item mFRI (yr fire-1)
#' \item mFRI_uCI (yr fire-1)
#' \item mFRI_lCI (yr fire-1)
#' \item WBLb (yr)
#' \item WBLb_uCI (yr)
#' \item WBLb_lCI (yr)
#' \item WBLc (unitless)
#' \item WBLc_uCI (unitless)
#' \item WBLc_lCI (unitless)
#' }
#'
#' ## NA / empty handling
#' \code{NA} values are written as empty fields (no quotes), matching
#' MATLAB's blank-cell convention. This applies to:
#' \itemize{
#' \item \code{smFRIs} rows beyond the smoothed-FRI coverage window;
#' \item zone-statistics columns (24-33) for rows beyond the last zone;
#' \item any column not computed for a given run configuration.
#' }
#'
#' ## CI column convention
#' MATLAB stores bootstrap CIs as \code{[quantile(2.5\%), quantile(97.5\%)]}
#' in the columns labelled \code{uCI} / \code{lCI} respectively (i.e.
#' \code{uCI} = lower bound, \code{lCI} = upper bound -- MATLAB's own
#' labelling is inverted). The R output follows the same convention so that
#' column indices are identical to the MATLAB reference file.
#'
#' @seealso [char_post_process()], [CharAnalysis()]
#'
#' @examples
#' \donttest{
#' # Run the pipeline on the bundled example and write results to tempdir:
#' params_file <- system.file("validation", "CO_charParams.csv",
#' package = "CharAnalysis")
#' out <- CharAnalysis(params_file)
#' char_write_results(out$char_results, out$site,
#' out_dir = tempdir())
#' }
#' @export
char_write_results <- function(char_results,
site,
out_dir,
digits = 7L) {
# ---- Validate inputs -------------------------------------------------------
if (missing(out_dir) || is.null(out_dir))
stop("Please supply 'out_dir', the directory to write the CSV file. ",
"Use tempdir() for a transient location, or a path of your choosing.",
call. = FALSE)
if (!is.character(out_dir) || length(out_dir) != 1L || nchar(out_dir) == 0L)
stop("'out_dir' must be a non-empty character string.", call. = FALSE)
if (!is.matrix(char_results) || ncol(char_results) != 33L)
stop("char_results must be a numeric matrix with exactly 33 columns.")
if (!is.character(site) || length(site) != 1L || nchar(site) == 0L)
stop("site must be a non-empty character string.")
if (!dir.exists(out_dir)) {
dir.create(out_dir, recursive = TRUE)
message("char_write_results: created output directory '", out_dir, "'")
}
# ---- Column headers (matching MATLAB charResults exactly) ------------------
col_headers <- c(
"cm Top_i (cm)",
"age Top_i (yr BP)",
"char Count_i (#)",
"char Vol_i (cm3)",
"char Con_i (# cm-3)",
"char Acc_i (# cm-2 yr-1)",
"charBkg (# cm-2 yr-1)",
"char Peak (# cm-2 yr-1)",
"thresh 1 (# cm-2 yr-1)",
"thresh 2 (# cm-2 yr-1)",
"thresh 3 (# cm-2 yr-1)",
"thresh FinalPos (# cm-2 yr-1)",
"thresh FinalNeg (# cm-2 yr-1)",
"SNI (index)",
"thresh GOF (p-val)",
"peaks 1",
"peaks 2",
"peaks 3",
"peaks Final",
"peaks Insig.",
"peak Mag (# cm-2 peak-1)",
"smPeak Frequ (peaks 1ka-1)",
"smFRIs (yr fire-1)",
"nFRIs (#)",
"mFRI (yr fire-1)",
"mFRI_uCI (yr fire-1)",
"mFRI_lCI (yr fire-1)",
"WBLb (yr)",
"WBLb_uCI (yr)",
"WBLb_lCI (yr)",
"WBLc (unitless)",
"WBLc_uCI (unitless)",
"WBLc_lCI (unitless)"
)
# ---- Format numeric matrix -------------------------------------------------
# Convert each column to character, respecting the digits argument.
# NA -> "" (blank cell, matching MATLAB blank-cell convention).
# Integer-valued columns (peaks, peakInsig) are written without decimals.
integer_cols <- 16:20 # peaks 1-Final, peakInsig -- always 0/1 integers
fmt_val <- function(x, is_int = FALSE) {
if (is.na(x)) return("")
if (is_int) return(as.character(as.integer(x)))
if (is.null(digits)) return(as.character(x))
# Match MATLAB's %g-style: use formatC with "g" format
formatC(x, digits = digits, format = "g", flag = "-")
}
N <- nrow(char_results)
out <- matrix("", nrow = N, ncol = 33L)
for (j in seq_len(33L)) {
is_int <- j %in% integer_cols
out[, j] <- vapply(char_results[, j], fmt_val,
FUN.VALUE = character(1L),
is_int = is_int)
}
# ---- Assemble data frame and write -----------------------------------------
df <- as.data.frame(out, stringsAsFactors = FALSE)
names(df) <- col_headers
out_path <- file.path(out_dir,
paste0(site, "_charResults.csv"))
# write.csv adds row names and quotes by default; use write.table for control
utils::write.table(df,
file = out_path,
sep = ",",
col.names = TRUE,
row.names = FALSE,
quote = FALSE,
na = "")
message("char_write_results: wrote '", out_path, "'")
invisible(out_path)
}
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.