% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/tsqca_ots_dts.R
\name{otSweep}
\alias{otSweep}
\title{OTS–QCA: Outcome threshold sweep}
\usage{
otSweep(
  dat,
  outcome = NULL,
  conditions = NULL,
  sweep_range,
  thrX,
  pre_calibrated = NULL,
  dir.exp = NULL,
  include = "",
  incl.cut = 0.8,
  n.cut = 1,
  pri.cut = 0,
  extract_mode = c("first", "all", "essential"),
  return_details = TRUE,
  Yvar = NULL,
  Xvars = NULL
)
}
\arguments{
\item{dat}{Data frame containing the outcome and condition variables.}

\item{outcome}{Character. Outcome variable name. Supports negation with
tilde prefix (e.g., \code{"~Y"}) following QCA package conventions.}

\item{conditions}{Character vector. Names of condition variables.}

\item{sweep_range}{Numeric vector. Candidate thresholds for Y.}

\item{thrX}{Named numeric vector. Fixed thresholds for X variables.
Names must match the conditions that require binarization.
Variables listed in \code{pre_calibrated} do not need a \code{thrX} entry.}

\item{pre_calibrated}{Character vector or \code{NULL}. Names of condition
variables that have been pre-calibrated (e.g., via \code{QCA::calibrate()})
and should be passed through to \code{QCA::truthTable()} without
binarization. These variables must contain values in the \code{[0, 1]}
range. Variables not listed here will be binarized using \code{thrX}
thresholds as usual. Default is \code{NULL} (all variables binarized).
It is recommended to sweep variables on their original (raw) scale rather
than as pre-calibrated fuzzy values, because raw-scale thresholds are
easier to interpret substantively.}

\item{dir.exp}{Directional expectations for \code{minimize}.
If \code{NULL} (default), no directional expectations are applied.
To compute the \strong{intermediate solution}, specify a numeric vector
(1, 0, or -1 for each condition). Example: \code{dir.exp = c(1, 1, 1)}
for three conditions all expected to contribute positively.}

\item{include}{Inclusion rule for \code{minimize}. 
\code{""} (default, QCA compatible) computes the \strong{complex solution}
without logical remainders.
Use \code{"?"} to include logical remainders for \strong{parsimonious}
(with \code{dir.exp = NULL}) or \strong{intermediate} solutions
(with \code{dir.exp} specified).}

\item{incl.cut}{Consistency cutoff for \code{truthTable}.}

\item{n.cut}{Frequency cutoff for \code{truthTable}.}

\item{pri.cut}{PRI cutoff for \code{minimize}.}

\item{extract_mode}{Character. How to handle multiple solutions:
\code{"first"} (default), \code{"all"}, or \code{"essential"}.
See \code{\link{qca_extract}} for details.}

\item{return_details}{Logical. If \code{TRUE} (default), returns both
summary and detailed objects for use with \code{generate_report()}.}

\item{Yvar}{Deprecated. Use \code{outcome} instead.}

\item{Xvars}{Deprecated. Use \code{conditions} instead.}
}
\value{
If \code{return_details = FALSE}, a data frame with columns:
\itemize{
  \item \code{thrY} — threshold for Y
  \item \code{expression} — minimized solution expression
  \item \code{inclS} — solution consistency
  \item \code{covS} — solution coverage
  \item (additional columns depending on \code{extract_mode})
}

If \code{return_details = TRUE}, a list with:
\itemize{
  \item \code{summary} — the data frame above
  \item \code{details} — per-Y-threshold list of
    \code{thrY}, \code{thrX_vec}, \code{truth_table}, \code{solution}
}

Note that \code{return_details} changes the \emph{type} of the returned
object, not just its contents: with \code{TRUE} the summary table is at
\code{result$summary}, whereas with \code{FALSE} the summary table
\emph{is} the returned object and \code{result$summary} is \code{NULL}.
Code intended to work under both settings should branch on
\code{inherits(result, "data.frame")} (or simply always pass
\code{return_details = TRUE}) rather than assuming \code{result$summary}
exists.
}
\description{
Sweeps the threshold of the outcome Y while keeping the thresholds of
all X conditions fixed.
}
\examples{
# Load sample data
data(sample_data)

# Set fixed thresholds for conditions
thrX <- c(X1 = 7, X2 = 7, X3 = 7)

# === Three Types of QCA Solutions ===

# 1. Complex Solution (default, QCA compatible)
#    Does not use logical remainders (most conservative)
result_comp <- otSweep(
  dat = sample_data,
  outcome = "Y",
  conditions = c("X1", "X2", "X3"),
  sweep_range = 7,
  thrX = thrX
  # include = "" (default), dir.exp = NULL (default)
)
head(result_comp$summary)

# 2. Parsimonious Solution (include = "?")
#    Uses logical remainders without directional expectations
result_pars <- otSweep(
  dat = sample_data,
  outcome = "Y",
  conditions = c("X1", "X2", "X3"),
  sweep_range = 7,
  thrX = thrX,
  include = "?"  # Include logical remainders
)
head(result_pars$summary)

# 3. Intermediate Solution (include = "?" + dir.exp)
#    Uses logical remainders with directional expectations
result_int <- otSweep(
  dat = sample_data,
  outcome = "Y",
  conditions = c("X1", "X2", "X3"),
  sweep_range = 7,
  thrX = thrX,
  include = "?",
  dir.exp = c(1, 1, 1)  # All conditions expected positive
)
head(result_int$summary)

# === Threshold Sweep Example ===

# Sweep with complex solutions (default)
result_sweep <- otSweep(
  dat = sample_data,
  outcome = "Y",
  conditions = c("X1", "X2", "X3"),
  sweep_range = 6:8,
  thrX = thrX
)
head(result_sweep$summary)

# Run with negated outcome (~Y)
# Analyzes conditions for Y < threshold
result_neg <- otSweep(
  dat = sample_data,
  outcome = "~Y",
  conditions = c("X1", "X2", "X3"),
  sweep_range = 6:8,
  thrX = thrX
)
head(result_neg$summary)
}
