% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/sol.df.R
\name{sol.df}
\alias{sol.df}
\title{Build a compact solution table from QCA minimization output}
\usage{
sol.df(
  conservative = NULL,
  intermediate = NULL,
  parsimonious = NULL,
  solution = "all",
  which_M = 1,
  i_mode = c("all", "C1P1"),
  branches = NULL,
  include_cases = TRUE,
  pi_incl_cut = NULL,
  digits = NULL,
  na_string = "-",
  verbose = FALSE
)
}
\arguments{
\item{conservative}{Optional conservative minimization result of class
\code{"QCA_min"}.}

\item{intermediate}{Optional intermediate minimization result of class
\code{"QCA_min"}.}

\item{parsimonious}{Optional parsimonious minimization result of class
\code{"QCA_min"}.}

\item{solution}{Which solution type to extract. Accepted values are
\code{"all"}, \code{"con"} or \code{"conservative"}, \code{"par"} or \code{"parsimonious"}, and
\code{"int"} or \code{"intermediate"}. When \code{solution = "all"}, the function
extracts every supplied object among \code{conservative}, \code{parsimonious}, and
\code{intermediate}.}

\item{which_M}{Positive integer giving which model to extract when a
supplied minimization object contains multiple models.}

\item{i_mode}{Character string controlling which intermediate branches to
extract when \code{intermediate} is supplied and \code{branches = NULL}. Accepted
values are \code{"all"} and \code{"C1P1"}.}

\item{branches}{Optional character vector of intermediate branch names to
extract from \code{intermediate$i.sol}. When supplied, this overrides \code{i_mode}.}

\item{include_cases}{Logical; if \code{TRUE}, include a \code{Cases} column using the
case information stored in the minimization object when available. Case
reconstruction expects the data-frame \code{pims} component produced by
\code{\link[QCA:minimize]{QCA::minimize()}}.}

\item{pi_incl_cut}{Optional lower cutoff applied to the prime-implicant
consistency column. Rows with \code{Consistency_PI < pi_incl_cut} are removed.}

\item{digits}{Optional non-negative integer used to round numeric columns in
the returned table.}

\item{na_string}{Single character string used to replace missing values in
non-numeric output fields. The default is \code{"-"}.}

\item{verbose}{Logical; if \code{TRUE}, print a short progress message while
processing each requested solution type.}
}
\value{
A data frame with one row per extracted prime implicant and the
following columns:
\describe{
\item{\code{Solution}}{Solution type label: \code{"Conservative"},
\code{"Parsimonious"}, or \code{"Intermediate"}.}
\item{\code{Model}}{Selected model number when model-specific output is
available.}
\item{\code{Intermediate_CnPn}}{Intermediate branch label when rows come from
\code{intermediate$i.sol}.}
\item{\code{Prime_Implicants}}{Prime implicant name.}
\item{\code{Consistency_PI}}{Prime-implicant consistency (\code{inclS}).}
\item{\code{PRI_PI}}{Prime-implicant PRI.}
\item{\code{Raw_Coverage_PI}}{Prime-implicant raw coverage (\code{covS}).}
\item{\code{Unique_Coverage_PI}}{Prime-implicant unique coverage (\code{covU}).}
\item{\code{Solution_Consistency}}{Solution-level consistency.}
\item{\code{Solution_PRI}}{Solution-level PRI.}
\item{\code{Solution_Coverage}}{Solution-level coverage.}
\item{\code{Cases}}{Case labels or case strings when available and requested.}
}

The function returns a regular data frame, not a custom result object.
}
\description{
Extracts prime implicants, fit statistics, model identifiers, intermediate
branch labels, and optional case membership strings from supplied
\code{\link[QCA:minimize]{QCA::minimize()}} result objects and returns them as one combined data
frame.
}
\details{
Supply at least one of \code{conservative}, \code{parsimonious}, or \code{intermediate}.

For conservative and parsimonious solutions, the function extracts rows from
the \code{IC} component of the supplied minimization object. For intermediate
solutions, it extracts rows from the selected \code{i.sol} branches.

If a supplied minimization object contains multiple models in
\code{IC$individual}, \code{which_M} selects the model position to extract. If the
requested model does not exist, the function stops with an error.

When \code{include_cases = TRUE}, the function first uses any \code{cases} column
already stored in the relevant \code{incl.cov} table. If that is unavailable, it
tries to reconstruct case strings from the corresponding \code{pims} data frame
stored by \code{\link[QCA:minimize]{QCA::minimize()}}.

The QCA solution-object conventions are described in \code{?qcaERT_conventions}.
}
\examples{
library(QCA)
data(LC)

conditions <- c("DEV", "URB", "LIT", "IND", "STB")
dir_exp <- rep("1", length(conditions))

tt <- truthTable(
  data = LC,
  outcome = "SURV",
  conditions = conditions,
  incl.cut = 0.8,
  n.cut = 1
)

enhanced <- findRows(tt, type = 2)

con <- minimize(
  input = tt,
  include = "",
  details = TRUE,
  show.cases = FALSE
)

par <- minimize(
  input = tt,
  include = "?",
  exclude = enhanced,
  details = TRUE,
  show.cases = FALSE
)

int <- minimize(
  input = tt,
  include = "?",
  dir.exp = dir_exp,
  exclude = enhanced,
  details = TRUE,
  show.cases = FALSE
)

sol.df(
  conservative = con,
  parsimonious = par,
  intermediate = int,
  solution = "all",
  which_M = 1,
  i_mode = "C1P1",
  include_cases = FALSE,
  digits = 2
)

\donttest{
library(QCA)
data(LR)

conditions <- c("DEV", "URB", "LIT", "IND", "STB")
outcome <- "SURV"
dir_exp <- rep("1", length(conditions))

thresholds <- list(
  DEV = findTh(LR$DEV, groups = 7),
  URB = findTh(LR$URB, groups = 4),
  LIT = findTh(LR$LIT, groups = 4),
  IND = findTh(LR$IND, groups = 4),
  STB = findTh(LR$STB, groups = 4),
  SURV = findTh(LR$SURV, groups = 4)
)

dat <- LR
dat$DEV <- calibrate(LR$DEV, type = "fuzzy", thresholds = thresholds$DEV)
dat$URB <- calibrate(LR$URB, type = "fuzzy", thresholds = thresholds$URB)
dat$LIT <- calibrate(LR$LIT, type = "fuzzy", thresholds = thresholds$LIT)
dat$IND <- calibrate(LR$IND, type = "fuzzy", thresholds = thresholds$IND)
dat$STB <- calibrate(LR$STB, type = "fuzzy", thresholds = thresholds$STB)
dat$SURV <- calibrate(LR$SURV, type = "fuzzy", thresholds = thresholds$SURV)

tt <- truthTable(
  data = dat,
  outcome = outcome,
  conditions = conditions,
  incl.cut = 0.8,
  n.cut = 1,
  complete = TRUE,
  show.cases = TRUE
)
enhanced <- findRows(tt, type = 2)

con <- minimize(tt, include = "", details = TRUE, show.cases = FALSE)
par <- minimize(tt, include = "?", exclude = enhanced, details = TRUE, show.cases = FALSE)
int <- minimize(
  tt,
  include = "?",
  dir.exp = dir_exp,
  exclude = enhanced,
  details = TRUE,
  show.cases = FALSE
)

sol.df(
  conservative = con,
  parsimonious = par,
  intermediate = int,
  solution = "all",
  which_M = 1,
  i_mode = "C1P1",
  include_cases = TRUE,
  digits = 3
)
}

}
\seealso{
\code{\link[=sol.chart]{sol.chart()}}, \code{\link[=calib.test]{calib.test()}}, \code{\link[=incl.test]{incl.test()}}, \code{\link[=ncut.test]{ncut.test()}},
\code{\link[=loo.test]{loo.test()}}, \code{\link[=subsample.test]{subsample.test()}}, \code{\link[=altset.test]{altset.test()}}, \code{\link[=theory.test]{theory.test()}},
\code{\link[=cluster.test]{cluster.test()}}
}
