% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/tabu_sem_shortform.R
\name{tabuShortForm}
\alias{tabuShortForm}
\title{Short Form Tabu Search}
\usage{
tabuShortForm(
  originalData,
  initialModel,
  numItems,
  criterion = function(x) {
     tryCatch(-lavaan::fitmeasures(object = x, fit.measures =
    "cfi"), error = function(e) Inf)
 },
  niter = 20,
  tabu.size = 5,
  lavaan.model.specs = list(int.ov.free = TRUE, int.lv.free = FALSE, std.lv = TRUE,
    auto.fix.first = FALSE, auto.fix.single = TRUE, auto.var = TRUE, auto.cov.lv.x =
    TRUE, auto.th = TRUE, auto.delta = TRUE, auto.cov.y = TRUE, ordered = NULL,
    model.type = "cfa", estimator = "default"),
  bifactor = FALSE,
  verbose = FALSE,
  parallel = T
)
}
\arguments{
\item{originalData}{The original data frame with variable names.}

\item{initialModel}{The initial model (typically the full form) as a character vector with lavaan model.syntax.}

\item{numItems}{A numeric vector indicating the number of items to retain for each factor.}

\item{criterion}{A function calculating the objective criterion to minimize. Default is to use the built-in `rmsea` value from `lavaan::fitmeasures()`.}

\item{niter}{A numeric value indicating the number of iterations (model specification selections)
to perform. Default is 50.}

\item{tabu.size}{A numeric value indicating the size of Tabu list. Default is 5.}

\item{lavaan.model.specs}{A list which contains the specifications for the
lavaan model. The default values are the defaults for lavaan to perform a
CFA. See \link[lavaan]{lavaan} for more details.}

\item{bifactor}{Logical. Indicates if the latent model is a bifactor model. If `TRUE`, assumes that the last latent variable in the provided model syntax is the bifactor (i.e., all of the retained items will be set to load on the last latent variable).}

\item{verbose}{Logical. If `TRUE`, prints out the initial short form and the selected short form at the end of each iteration.}

\item{parallel}{An option for using parallel processing. If \code{TRUE}, the 
function will utilize all available cores. Default is \code{TRUE}.}
}
\value{
A named list with the best value of the objective function (`best.obj`) and the best lavaan model object (`best.mod`).
}
\description{
Given an initial (full) lavaan model string, the original data, a criterion
function to minimize, and some additional specifications,
performs a Tabu model specification search. Currently only supports
neighbors that are 1 move away from the current model.
}
\examples{
shortAntModel <- "
Ability =~ Item1 + Item2 + Item3 + Item4 + Item5 + Item6 + Item7 + Item8
Ability ~ Outcome
"

data(simulated_test_data)
tabuResult <- tabuShortForm(
  initialModel = shortAntModel,
  originalData = simulated_test_data, numItems = 7,
  niter = 1, tabu.size = 3, parallel = FALSE
)
summary(tabuResult) # shows the resulting model
\dontrun{
# create simulation data from the `psych` package
# four factors, 12 items each, 48 total items
# factor loading matrix - not quite simple structure
fxMatrix <-
  matrix(
    data = c(
      rep(x = c(.9, .7, .5, .3), times = 3),
      rep(0.2, times = 3 * 4 * 3), # first factor loadings

      rep(0.2, times = 3 * 4),
      rep(x = c(.9, .7, .5, .3), times = 3),
      rep(0.2, times = 3 * 4 * 2), # second factor loadings

      rep(0.2, times = 3 * 4 * 2),
      rep(x = c(.9, .7, .5, .3), times = 3),
      rep(0.2, times = 3 * 4), # third factor loadings

      rep(0.2, times = 3 * 4 * 3),
      rep(x = c(.9, .7, .5, .3), times = 3) # fourth factor loadings
    ),
    ncol = 4
  )
# factor correlation matrix - all factors uncorrelated
PhiMatrix <-
  matrix(data = c(
    1, 0, 0, 0,
    0, 1, 0, 0,
    0, 0, 1, 0,
    0, 0, 0, 1
  ), ncol = 4)
tabuData <-
  psych::sim(
    fx = fxMatrix,
    Phi = PhiMatrix,
    n = 1000,
    raw = TRUE
  )$observed # observed is the simulated observed data

# NOTE: you must specify the model such that each factor is on a single line!
# otherwise, the algorithm will not work correctly!
tabuModel <- "
Trait1 =~ Item1 + Item2 + Item3 + Item4 + Item5 + Item6 +
Item7 + Item8 + Item9 + Item10 + Item11 + Item12
Trait2 =~ Item13 + Item14 + Item15 + Item16 + Item17 +
Item18 + Item19 + Item20 + Item21 + Item22 + Item23 + Item24
Trait3 =~ Item25 + Item26 + Item27 + Item28 + Item29 + Item30 +
Item31 + Item32 + Item33 + Item34 + Item35 + Item36
Trait4 =~ Item37 + Item38 + Item39 + Item40 + Item41 +
Item42 + Item43 + Item44 + Item45 + Item46 + Item47 + Item48
"

colnames(tabuData) <- paste0("Item", 1:48)
# specify the criterion function that the Tabu Search minimizes
# wrap this in a tryCatch in case a model does not converge!
# specify an appropriate error value: if minimizing, error value must be large
tabuCriterion <- function(x) {
  tryCatch(lavaan::fitmeasures(object = x, fit.measures = "chisq"),
    error = function(e) Inf
  )
}

# use the tabuShortForm function
# reduce form to the best 12 items
tabuShort <- tabuShortForm(
  initialModel = tabuModel, originalData = tabuData,
  numItems = c(3, 3, 3, 3),
  criterion = tabuCriterion,
  niter = 20, tabu.size = 10
)
}

}
