R/specify_constructs.R

Defines functions higher_composite higher_reflective single_item multi_items composite reflective constructs

Documented in composite constructs higher_composite higher_reflective multi_items reflective single_item

#' Measurement functions
#'
#' \code{constructs} creates the constructs from measurement items by assigning the
#' relevant items to each construct and specifying reflective or formative (composite/causal) measurement models
#'
#' This function conveniently maps measurement items to constructs using
#' root name, numbers, and affixes with explicit definition of formative
#' or reflective relationships
#'
#' @param ... Comma separated list of the construct variable measurement specifications, as generated by the
#'    \code{reflective()}, or \code{composite()} methods.
#'
#' @return A list of constructs, their indicators and estimation technique (SEMinR measurement model).
#'
#' @usage
#'   constructs(...)
#'
#' @seealso See \code{\link{composite}}, \code{\link{reflective}}
#'
#' @examples
#'   mobi_mm <- constructs(
#'     reflective("Image",        multi_items("IMAG", 1:5)),
#'     reflective("Expectation",  multi_items("CUEX", 1:3)),
#'     reflective("Quality",      multi_items("PERQ", 1:7)),
#'     reflective("Value",        multi_items("PERV", 1:2)),
#'     reflective("Satisfaction", multi_items("CUSA", 1:3)),
#'     reflective("Complaints",   single_item("CUSCO")),
#'     reflective("Loyalty",      multi_items("CUSL", 1:3))
#'   )
#' @export
constructs <- function(...) {
  return_list <- list(...)
  names(return_list) <- lapply(return_list, function(x) class(x)[[3]])
  class(return_list) <- c(class(return_list), "measurement_model", "seminr_model")
  return(return_list)
}

#' Reflective construct measurement model specification
#'
#' \code{reflective} creates the reflective measurement model matrix for a specific common-factor,
#' specifying the relevant items of the construct and assigning the relationship of reflective.
#' By definition this construct will be estimated by PLS consistent.
#'
#' This function conveniently maps reflectively defined measurement items to a construct and is estimated
#' using PLS consistent.
#'
#' @param construct_name of construct
#' @param item_names returned by the \code{multi_items} or \code{single_item} functions
#'
#' @usage
#'  reflective(construct_name, item_names)
#'
#' @return A vector of the indicators for a reflective construct.
#'
#' @seealso See \code{\link{composite}}, \code{\link{constructs}}
#'
#' @examples
#'   mobi_mm <- constructs(
#'     reflective("Image",        multi_items("IMAG", 1:5)),
#'     reflective("Expectation",  multi_items("CUEX", 1:3)),
#'     reflective("Quality",      multi_items("PERQ", 1:7)),
#'     reflective("Value",        multi_items("PERV", 1:2)),
#'     reflective("Satisfaction", multi_items("CUSA", 1:3)),
#'     reflective("Complaints",   single_item("CUSCO")),
#'     reflective("Loyalty",      multi_items("CUSL", 1:3))
#'   )
#' @export
reflective <- function(construct_name, item_names) {
  construct_names <- rep(construct_name, length(item_names))
  construct <- c(rbind(construct_names, item_names, "C"))
  class(construct) <- c(class(construct), c("construct", "reflective"))
  return(construct)
}

#' Composite construct measurement model specification
#'
#' \code{composite} creates the composite measurement model matrix for a specific construct,
#' specifying the relevant items of the construct and assigning the relationship of either
#' correlation weights (Mode A) or regression weights (Mode B).
#'
#' This function conveniently maps composite defined measurement items to a construct and is
#' estimated using PLS.
#'
#' @param construct_name of construct
#' @param item_names returned by the \code{multi_items} or \code{single_item} functions
#' @param weights is the relationship between the construct and its items. This can be
#' specified as \code{correlation_weights} or \code{mode_A} for correlation weights (Mode A) or as
#' \code{regression_weights} or \code{mode_B} for regression weights (Mode B). Default is correlation weights.
#'
#' @return A vector of the indicators for a composite.
#'
#' @usage
#'  composite(construct_name, item_names,weights = correlation_weights)
#'
#' @seealso See \code{\link{constructs}}, \code{\link{reflective}}
#'
#' @examples
#'   mobi_mm <- constructs(
#'     composite("Image",        multi_items("IMAG", 1:5), weights = correlation_weights),
#'     composite("Expectation",  multi_items("CUEX", 1:3), weights = mode_A),
#'     composite("Quality",      multi_items("PERQ", 1:7), weights = regression_weights),
#'     composite("Value",        multi_items("PERV", 1:2), weights = mode_B)
#'   )
#' @export
composite <- function(construct_name, item_names, weights = correlation_weights) {
  if (identical(weights, correlation_weights)) {
    composite_type = "A"
  } else if (identical(weights, regression_weights)) {
    composite_type = "B"
  } else if (identical(weights, unit_weights)) {
    composite_type = "UNIT"
  } else {
    stop("Composites must be defined as mode A (correlation weights) or B (regression weights)")
  }
  construct <- c(rbind(construct_name, item_names, composite_type))
  class(construct) <- c(class(construct), c("construct", "composite"))
  return(construct)
}

# arguments:
#   item_name: root name of all items
#   item_numbers: vector of item numbers
#   ...: optional affix arguments
#     prefix: prefix before each item name
#     mid: insert between item name and numbers
#     suffix: suffix after each ite name
#
# e.g.> multi_items("item", 0:3, prefix="X_", mid=".", suffix="_")


#' Multi-items measurement model specification
#'
#' \code{multi_items} creates a vector of measurment names given the item prefix and number range.
#'
#' @param item_name Prefix name of items
#' @param item_numbers The range of number suffixews for the items
#' @param ... Additional Item names and nubers
#'
#' @return A vector of numbered indicators.
#'
#' @usage
#'   multi_items(item_name, item_numbers, ...)
#'
#' @seealso See \code{\link{single_item}}
#'
#' @examples
#'   mobi_mm <- constructs(
#'     composite("Image",        multi_items("IMAG", 1:5), weights = correlation_weights),
#'     composite("Expectation",  multi_items("CUEX", 1:3), weights = mode_A),
#'     composite("Quality",      multi_items("PERQ", 1:7), weights = regression_weights),
#'     composite("Value",        multi_items("PERV", 1:2), weights = mode_B)
#'   )
#' @export
multi_items <- function(item_name, item_numbers, ...) {
  affix <- as.data.frame(list(...))
  paste(affix$prefix, item_name, affix$mid, item_numbers, affix$suffix, sep = "")
}

#' Single-item measurement model specification
#'
#' \code{single_item} specifies a single item name to be assigned to a construct.
#'
#' @param item Name of item
#'
#' @return A vector of a single indicator for a composite.
#'
#' @usage
#'   single_item(item)
#'
#' @seealso See \code{\link{multi_items}}
#'
#' @examples
#'   mobi_mm <- constructs(
#'     composite("Image",        multi_items("IMAG", 1:5), weights = correlation_weights),
#'     composite("Expectation",  multi_items("CUEX", 1:3), weights = mode_A),
#'     composite("Quality",      multi_items("PERQ", 1:7), weights = regression_weights),
#'     composite("Value",        single_item("PERV1"))
#'   )
#' @export
single_item <- function(item) {
  return(item)
}

#' higher_reflective
#'
#' \code{higher_reflective} creates a higher-order reflective construct
#'
#' This function maps first-order constructs onto second-order reflective constructs using
#' construct names. It is currently only suitable for CB-SEM and not PLS
#'
#' @param construct_name of second-order construct
#' @param dimensions the first-order constructs
#'
#' @usage
#'  higher_reflective(construct_name, dimensions)
#'
#' @return A vector of the indicators for a higher-order-factor.
#'
#' @seealso See \code{\link{constructs}}, \code{\link{reflective}}
#'
#' @examples
#'   mobi_mm <- constructs(
#'     reflective("Image",           multi_items("IMAG", 1:5)),
#'     reflective("Expectation",     multi_items("CUEX", 1:3)),
#'     higher_reflective("Quality",  c("Image", "Expectation"))
#'   )
#' @export
higher_reflective <- function(construct_name, dimensions) {
  construct <- reflective(construct_name = construct_name, item_names = dimensions)
  class(construct) <- c(class(construct)[1], c("construct", "higher_order_reflective"))
  return(construct)
}

#' higher_composite
#'
#' \code{higher_composite} creates a higher order construct from first-order constructs using the two-stage method (Becker et al., 2012).
#'
#' This function conveniently maps first-order constructs onto second-order constructs using
#' construct names.
#'
#' @param construct_name of second-order construct
#' @param dimensions the first-order constructs
#' @param method is the estimation method, default is two_stage
#' @param weights is the relationship between the second-order construct and first-order constructs. This can be
#' specified as \code{correlation_weights} or \code{mode_A} for correlation weights (Mode A) or as
#' \code{regression_weights} or \code{mode_B} for regression weights (Mode B). Default is correlation weights.
#'
#' @usage
#'  higher_composite(construct_name, dimensions, method, weights)
#'
#' @return A vector of the indicators for a higher-order-composite.
#'
#' @seealso See \code{\link{constructs}}, \code{\link{reflective}}
#'
#' @examples
#'   mobi_mm <- constructs(
#'     composite("Image",        multi_items("IMAG", 1:5), weights = correlation_weights),
#'     composite("Expectation",  multi_items("CUEX", 1:3), weights = mode_A),
#'     higher_composite("Quality",  c("Image","Expectation"), method = two_stage),
#'     composite("Value",        multi_items("PERV", 1:2), weights = mode_B)
#'   )
#' @export
higher_composite <- function(construct_name, dimensions, method = two_stage,  weights = correlation_weights) {
  # TODO remove the duplicated conditional
  if (identical(weights, correlation_weights)) {
    composite_type = "HOCA"
  } else if (identical(weights, regression_weights)) {
    composite_type = "HOCB"
  } else if (identical(weights, unit_weights)){
    composite_type = "UNIT"
  } else {
    stop("Composites must be defined as mode A (correlation weights) or B (regression weights)")
  }
  construct <- c(rbind(construct_name, dimensions, composite_type))
  class(construct) <- c(class(construct), c("construct", "higher_order_composite"))
  return(construct)
}
sem-in-r/seminr documentation built on Aug. 26, 2022, 8:47 p.m.