% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/get_solution.R
\name{get_features}
\alias{get_features}
\title{Get feature summary from a solution}
\usage{
get_features(x, run = NULL)
}
\arguments{
\item{x}{A \code{Solution} or \code{SolutionSet} object returned by
\code{\link{solve}}.}

\item{run}{Optional positive integer giving the run index to extract from a
\code{SolutionSet}. If \code{NULL}, all runs are returned when available.}
}
\value{
A \code{data.frame} with one row per feature, or one row per
feature--run combination when multiple runs are present. The returned table
always includes the columns \code{total_available}, \code{benefit},
\code{loss}, \code{net}, and \code{total}.
}
\description{
Extract the per-feature summary table from a \code{Solution} or
\code{SolutionSet} object returned by \code{\link{solve}}.

The returned table summarizes, for each feature, the total amount available
in the landscape together with the positive and negative contributions induced
by the selected actions in the solution.
}
\details{
This function reads the feature summary stored in \code{x$summary$features}.
It errors if that table is missing.

Let \eqn{B_f} denote the total baseline amount available in the landscape for
feature \eqn{f}. Let \eqn{G_f} denote the total positive contribution induced
by selected actions, and let \eqn{L_f} denote the total negative
contribution. Then the returned table is intended to summarize quantities of
the form:

\deqn{
\mathrm{net}_f = G_f - L_f,
}

\deqn{
\mathrm{total}_f = B_f + \mathrm{net}_f.
}

In the stored summary, these quantities are typically represented by the
columns:
\itemize{
\item \code{total_available}, corresponding to \eqn{B_f},
\item \code{benefit}, corresponding to \eqn{G_f},
\item \code{loss}, corresponding to \eqn{L_f},
\item \code{net}, corresponding to \eqn{G_f - L_f},
\item \code{total}, corresponding to \eqn{B_f + G_f - L_f}.
}

If any of the core numeric columns \code{total_available}, \code{benefit}, or
\code{loss} are missing, they are created and filled with zero. If
\code{net} is missing, it is computed as \code{benefit - loss}. If
\code{total} is missing, it is computed as \code{total_available + net}.

Thus, this function guarantees that the returned table contains the columns
\code{total_available}, \code{benefit}, \code{loss}, \code{net}, and
\code{total}, even if some of them were absent from the stored summary.

If \code{x} is a \code{SolutionSet} and \code{run} is provided, only rows
belonging to that run are returned. If the result contains a \code{run_id}
column but only a single run is present and \code{run} was not requested
explicitly, the \code{run_id} column is removed for convenience.

This function summarizes feature outcomes in the solution. It is different
from \code{\link{get_targets}}, which focuses on target achievement rather
than total feature balance.
}
\examples{
\donttest{
if (requireNamespace("rcbc", quietly = TRUE)) {
  pu_tbl <- data.frame(
    id = 1:4,
    cost = c(1, 2, 3, 4)
  )

  feat_tbl <- data.frame(
    id = 1:2,
    name = c("feature_1", "feature_2")
  )

  dist_feat_tbl <- data.frame(
    pu = c(1, 1, 2, 3, 4),
    feature = c(1, 2, 2, 1, 2),
    amount = c(5, 2, 3, 4, 1)
  )

  actions_df <- data.frame(
    id = "conservation",
    name = "conservation"
  )

  effects_df <- data.frame(
    pu = c(1, 2, 3, 4),
    action = "conservation",
    feature = c(1, 1, 2, 2),
    benefit = c(2, 1, 1, 2),
    loss = c(0, 0, 0, 0)
  )

  p <- create_problem(
    pu = pu_tbl,
    features = feat_tbl,
    dist_features = dist_feat_tbl,
    cost = "cost"
  ) |>
    add_actions(actions_df, cost = 0) |>
    add_effects(effects_df) |>
    add_constraint_targets_relative(0.2) |>
    add_objective_min_cost() |>
    set_solver_cbc(time_limit = 10)

  sol <- solve(p)

  get_features(sol)
}
}

}
\seealso{
\code{\link{get_pu}},
\code{\link{get_actions}},
\code{\link{get_targets}}
}
