% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/export_candidates_csv.R
\name{svem_export_candidates_csv}
\alias{svem_export_candidates_csv}
\title{Export SVEM candidate sets to CSV}
\usage{
svem_export_candidates_csv(
  ...,
  file = NULL,
  overwrite = FALSE,
  write_file = TRUE
)
}
\arguments{
\item{...}{One or more objects returned by
\code{\link{svem_select_from_score_table}}. You may also pass a single
list of such objects.}

\item{file}{Character scalar; path to the CSV file to be written.
Required only when \code{write_file = TRUE}.}

\item{overwrite}{Logical; if \code{FALSE} (default) and \code{file}
already exists, an error is thrown. If \code{TRUE}, any existing file
at \code{file} is overwritten. Only used when \code{write_file = TRUE}.}

\item{write_file}{Logical; if \code{TRUE} (default), write the combined
table to \code{file} as CSV and print the full path. If \code{FALSE},
no file is written and \code{file} may be \code{NULL}; the concatenated
\code{data.frame} is still returned (invisibly).}
}
\value{
Invisibly, the \code{data.frame} that was written to CSV (or
would be written, when \code{write_file = FALSE}).
}
\description{
Given one or more selection objects returned by
\code{\link{svem_select_from_score_table}}, concatenate their
\code{$best} rows and \code{$candidates} and export a CSV suitable for
planning new experimental runs.

Each row is tagged with:
\itemize{
\item \code{candidate_type}: \code{"best"} or \code{"medoid"}.
\item \code{selection_label}: derived from the \code{label} argument
used in \code{svem_select_from_score_table()} when available.
}

The function does not modify any response or prediction columns (for
example, \code{Potency}, \code{Potency_pred}); it simply harmonizes
columns across inputs (adding \code{NA}-filled columns where necessary),
concatenates rows, and reorders a few metadata columns for readability.

Any columns named \code{candidate_type}, \code{selection_label}, or
\code{Notes_from_SVEMnet} that are present in the final data frame are moved to the
leftmost positions in that order.
}
\examples{
\donttest{
# 1) Load example data
data(lipid_screen)

# 2) Build a deterministic expansion using bigexp_terms()
spec <- bigexp_terms(
  Potency ~ PEG + Helper + Ionizable + Cholesterol +
    Ionizable_Lipid_Type + N_P_ratio + flow_rate,
  data             = lipid_screen,
  factorial_order  = 3,   # up to 3-way interactions
  polynomial_order = 3,   # include up to cubic terms I(X^2), I(X^3)
  include_pc_2way  = TRUE,
  include_pc_3way  = FALSE
)

# 3) Shared deterministic expansion for all three responses
form_pot <- bigexp_formula(spec, "Potency")
form_siz <- bigexp_formula(spec, "Size")
form_pdi <- bigexp_formula(spec, "PDI")

# 4) Fit SVEM models
set.seed(1)
fit_pot <- SVEMnet(form_pot, lipid_screen)
fit_siz <- SVEMnet(form_siz, lipid_screen)
fit_pdi <- SVEMnet(form_pdi, lipid_screen)

objs <- list(Potency = fit_pot, Size = fit_siz, PDI = fit_pdi)

# 5) Multi-response goals (DS desirabilities under the hood)
goals <- list(
  Potency = list(goal = "max", weight = 0.6),
  Size    = list(goal = "min", weight = 0.3),
  PDI     = list(goal = "min", weight = 0.1)
)

# 6) Mixture constraints on the four lipid components
mix <- list(list(
  vars  = c("PEG", "Helper", "Ionizable", "Cholesterol"),
  lower = c(0.01, 0.10, 0.10, 0.10),
  upper = c(0.05, 0.60, 0.60, 0.60),
  total = 1.0
))

# 7) Optional process-mean specifications for a design-space example
specs_ds <- list(
  Potency = list(lower = 78),
  Size    = list(upper = 100),
  PDI     = list(upper = 0.25)
)

# 8) Random-search scoring (predictions stored in *_pred columns)
set.seed(3)
scored <- svem_score_random(
  objects         = objs,
  goals           = goals,
  data            = lipid_screen,
  n               = 2500,
  mixture_groups  = mix,
  level           = 0.95,
  combine         = "geom",
  numeric_sampler = "random",
  specs           = specs_ds,
  verbose         = FALSE
)

# 9) Build several selection objects from the scored table

# High-score optimal medoids (user-weighted score)
opt_sel <- svem_select_from_score_table(
  score_table = scored$score_table,
  target      = "score",
  direction   = "max",
  k           = 5,
  top_type    = "frac",
  top         = 0.02,
  label       = "round1_score_optimal"
)

# High-uncertainty exploration medoids
explore_sel <- svem_select_from_score_table(
  score_table = scored$score_table,
  target      = "uncertainty_measure",
  direction   = "max",
  k           = 5,
  top_type    = "frac",
  top         = 0.05,
  label       = "round1_explore"
)

# High joint mean-in-spec medoids (design-space view)
inspec_sel <- svem_select_from_score_table(
  score_table = scored$score_table,
  target      = "p_joint_mean",
  direction   = "max",
  k           = 5,
  top_type    = "frac",
  top         = 0.10,
  label       = "round1_inspec"
)

# Best existing screened run (from original_data_scored; k <= 0 -> no medoids)
best_existing <- svem_select_from_score_table(
  score_table = scored$original_data_scored,
  target      = "score",
  direction   = "max",
  k           = 0,
  top_type    = "frac",
  top         = 1.0,
  label       = "round1_existing_best"
)

# 10) Combine all selection objects in a single list
candidate_sels <- list(
  opt_sel,
  explore_sel,
  inspec_sel,
  best_existing
)

# 11a) Export all candidates to CSV for the next experimental round
# svem_export_candidates_csv(
#   candidate_sels,
#   file       = "lipid_screen_round1_candidates.csv",
#   overwrite  = FALSE,
#   write_file = TRUE
# )

# 11b) Or inspect the combined table in-memory without writing a file
cand_tbl <- svem_export_candidates_csv(
  candidate_sels,
  write_file = FALSE
)
head(cand_tbl)

# 11c) Alternatively, pass selection objects directly as separate arguments
cand_tbl2 <- svem_export_candidates_csv(
  opt_sel,
  explore_sel,
  inspec_sel,
  best_existing,
  write_file = FALSE
)
head(cand_tbl2)
}

}
