% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/estimate_factorscores.R
\name{estimate_factorscores_rcpp}
\alias{estimate_factorscores_rcpp}
\title{Estimate Factor Scores}
\usage{
estimate_factorscores_rcpp(
  result,
  data,
  control = NULL,
  parallel = FALSE,
  verbose = TRUE,
  include_prior = FALSE,
  id_var = NULL
)
}
\arguments{
\item{result}{A factorana_result object from estimate_model_rcpp()}

\item{data}{Data frame containing all variables (same as used in estimation)}

\item{control}{Optional estimation control object. If NULL, uses default.}

\item{parallel}{Whether to use parallel computation (default FALSE).
When TRUE, uses the num_cores setting from control.}

\item{verbose}{Whether to print progress (default TRUE)}

\item{include_prior}{Whether to include the factor prior in likelihood/SE
computation (default FALSE). When FALSE, matches legacy C++ behavior where
SEs are based only on observation likelihood. When TRUE, includes the prior
contribution to the Hessian, resulting in smaller SEs.}

\item{id_var}{Optional character string specifying the name of an ID variable
in data. If provided, this variable is included in the output data frame for
easier merging with other datasets. The ID values are taken from the original
data in the order observations were processed. Note: The ID column must be
numeric (not character) since data is converted to a numeric matrix. For
character IDs, use the obs_id column to merge with your original data.}
}
\value{
A data frame with columns:
\itemize{
\item \code{obs_id} - Observation index (1-based)
\item \code{<id_var>} - ID variable values (if id_var was specified)
\item \code{factor_1, factor_2, ...} - Estimated factor scores
\item \code{se_factor_1, se_factor_2, ...} - Standard errors
\item \code{converged} - Whether optimization converged for this observation
\item \code{log_posterior} - Log-posterior value at the mode
}
}
\description{
Estimates factor scores for each observation after model estimation.
The model parameters are held fixed at their estimated values, and
factor scores are computed as the posterior mode for each observation.
}
\details{
Factor scores are estimated by maximizing the posterior density:
\deqn{L(f|y_i, \theta) = p(y_i|f, \theta) \cdot \phi(f|0, \sigma^2)}

where:
\itemize{
\item \eqn{f} is the vector of factor values for observation i
\item \eqn{y_i} is the observed data for observation i
\item \eqn{\theta} are the fixed model parameters (from previous estimation)
\item \eqn{\phi(f|0, \sigma^2)} is the normal prior on factors
}

Standard errors are computed from the diagonal of the inverse Hessian
of the log-posterior at the mode. By default (include_prior=FALSE), the SE
is based only on the observation likelihood Hessian, matching the legacy
C++ implementation. Set include_prior=TRUE to include the prior's Hessian
contribution (-1/sigma^2) which produces smaller SEs.

When parallel=TRUE, observations are distributed across cores using
doParallel/foreach, with each worker processing a subset of observations.
}
\examples{
\donttest{
# Estimate a small one-factor model, then recover factor scores
set.seed(1); n <- 200
f <- rnorm(n)
dat <- data.frame(intercept = 1,
                  y1 = 1.0 * f + rnorm(n, 0, 0.5),
                  y2 = 0.8 * f + rnorm(n, 0, 0.5))
fm <- define_factor_model(n_factors = 1)
mc1 <- define_model_component("m1", dat, "y1", fm,
  covariates = "intercept", model_type = "linear",
  loading_normalization = 1)
mc2 <- define_model_component("m2", dat, "y2", fm,
  covariates = "intercept", model_type = "linear",
  loading_normalization = NA_real_)
ms <- define_model_system(components = list(mc1, mc2), factor = fm)
ctrl <- define_estimation_control(n_quad_points = 8, num_cores = 1)
fit <- estimate_model_rcpp(ms, dat, control = ctrl,
  optimizer = "nlminb", parallel = FALSE, verbose = FALSE)

fscores <- estimate_factorscores_rcpp(fit, dat, control = ctrl,
                                       parallel = FALSE, verbose = FALSE)
head(fscores)
}

}
