FAiR (version 0.4-15)

make_restrictions: Make an object of class "restrictions"

Description

This function is intended for users and sets up the restrictions to be imposed on the factor analysis model, which includes specifying whether an exploratory, confirmatory, or semi-exploratory model is to be estimated and what discrepancy function to use. It is a prerequisite for calling Factanal and assumes you have already called make_manifest.

However, it is not necessary to understand the function arguments in great detail because most of the functionality is implemented via pop-up menus. The vignette provides the “substantive” documentation for this function and provides screenshots of the pop-up menus; execute vignette("FAiR") to view it. It is possible (though not recommended in normal usage) to avoid the pop-up menus entirely, in which case it is necessary to thoroughly understand the documentation here and in the vignette as well as the restrictions-class definition.

In technical terms, this S4 generic function is a constructor for objects of restrictions-class. The arguments in the signature of the S4 generic function are: manifest, Omega, beta, Phi, Delta, and Xi The first S4 method defined immediately below is the one indended for the vast majority of usage. It requires manifest to be specified, forbids these Greek letters from being specified, and has a few optional arguments that can be specified to modify the default behavior.

Usage

"make_restrictions"( manifest, factors = NULL, model = c("SEFA", "EFA", "CFA"), discrepancy = "default", nl_1 = NULL, nl_2 = NULL)
# USE THE ABOVE METHOD IN MOST CASES!!! # USE ONE OF THE FOLLOWING METHODS IN SIMULATIONS, ETC.
# Model | Omega | beta | Phi | Delta | Xi # --------------------------------------------------------- # 0 common factors | X | | | | # EFA | | X | | | # Correlated factors | | X | X | | # Correlated factors | X | X | X | | # 1 second-order factor | | X | | X | # 1 second-order factor | X | X | | X | # Second-order factors | | X | | X | X # Second-order factors | X | X | | X | X
# An X indicates that the argument named by the column is specified # No X indicates that the argument named by the column is missing # All take an object that inherits from the manifest.basic class as the first argument # In addition, there are two arguments that are not part of the signature: # criteria -- either NULL or a list (possibly of length zero) of functions or character # strings naming functions to be used as criteria in the lexical optimization process. # methodArgs -- a list (possibly of length zero) of required arguments to the functions # listed in the criteria argument.

Arguments

manifest
a required object that inherits from manifest.basic-class
Omega
usually missing or else an object of parameter.scale-class
beta
usually missing or else an object that inherits from parameter.coef-class
Phi
usually missing or else an object of parameter.cormat-class
Delta
usually missing or else an object that inherits from parameter.coef-class
Xi
usally missing or else an object of parameter.cormat-class
factors
either NULL or a vector of length one or two indicating the number of factors at level one and level two
model
a character string among "SEFA" (default), "CFA", and "EFA" indicating whether to estimate a semi-exploratory, confirmatory, or exploratory model
discrepancy
a character string among "default", "MLE", "ADF", "ELLIPTICAL", "HK", "SHK", and "YWLS" indicating which discrepancy function to use. The default behavior is "ADF" if possible, otherwise "MLE". See the Note section for details.
nl\_1
either NULL or a function with an argument called x that imposes nonlinear exact restrictions on some cells of the primary pattern matrix at level one. See the Details section.
nl\_2
either NULL or a function with an argument called x that imposes nonlinear exact restrictions on some cells of the primary pattern matrix at level two. See the Details section.

Value

Returns an object that inherits from restrictions-class. This object would then be passed to the restrictions argument of Factanal.

Details

Let the factor analysis model in the population be $$\Sigma = \Omega(\beta\Phi\beta^\prime + \Theta)\Omega$$ where $Sigma$ is the covariance matrix among outcome variables, $Omega$ is a diagonal matrix of standard deviations of the manifest variables, $beta$ is the primary pattern matrix (calibrated to standardized variables) with one column per factor, $Phi$ is the correlation matrix among the primary factors, and $Theta$ is the diagonal matrix of uniquenesses, which is fully determined by $beta$, $Phi$, and the requirement that the matrix within parentheses has ones down its diagonal. Hence, $beta Phi beta' + Theta$ is the model's correlation matrix among outcome variables as a function of the factors. This parameterization is often attributed to Cudeck (1989, equation 21) or to Krane and McDonald (1975) and will essentially yield the correct results even if the model is fit to a correlation matrix.

The make_restrictions methods set up the right-hand side of the factor analysis model, including the restrictions that are placed on the parameters. FAiR differs fundamentally from other factor analysis software in that you can place inequality restrictions on functions of multiple parameters, although this mechanism is not permitted during the factor extraction stage of an exploratory factor analysis. The classes that inherit from restrictions-class typically have slots that are Greek letters, which are objects that inherit from parameter-class. But the restrictions-class has additional slots that contain other information about the model.

Exploratory factor analysis (EFA) requires a minimal set of restrictions and permits no additional restrictions in the factor extraction stage. EFA preliminarily assumes the factors are orthogonal, i.e. $Phi = I$, and either assumes that $beta' Theta^-1 beta$ is diagonal or that $beta$ has all zeros in its upper triangle. However, after a transformation of the factors has been chosen (see Rotate), EFA takes no strong position on how many or which cells of $beta$ are (near) zero, unless target rotation or the simplimax criterion is used.

Confirmatory factor analysis (CFA) allows the user to choose which cells of $beta$ are exactly zero according to substantive theory and also permits other kinds of restrictions. Semi-exploratory factor analysis (SEFA) allows the user to choose how many cells in each column of $beta$ are zero but does not require the user to specify which cells are zero. SEFA also permits other kinds of restrictions, including constraining specific cells in $beta$ to be zero, as in a CFA.

For CFA and SEFA, it is optionally possible to estimate a “two-level” model where the correlation matrix among first-order factors is a function of one or more second-order factors. Hence, let the second-order factor analysis model in the population be $$\Phi = \Delta\Xi\Delta^\prime + \Gamma$$ where $Phi$ is the correlation matrix among first-order primary factors, $Delta$ is the second-order primary pattern matrix with one column per factor, $Xi$ is the correlation matrix among the second-order primary factors, and $Gamma$ is the diagonal matrix of second-order uniquenesses, which is fully determined by $Delta$, $Xi$, and the requirement that $Phi$ has ones down its diagonal. Hence, in a two-level model, $Phi$ is restricted to be an exact function of $Delta$ and $Xi$ and the parameters for the two levels are estimated simultaneously.

If you are at all unsure about what to do, use the first method listed in the Usage section, where "manifest" is the only required argument. This method covers all the functionality of the other methods and will walk you through all the necessary steps using pop-up menus. However, if you would like to impose any nonlinear exact restrictions on the cells of $beta$ or $Delta$, then you need to define such functions (whose first argument should be called "x") in the global environment and specify them as the nl_1 and / or nl_2. See also parameter.coef.nl-class for details.

The other methods will ask fewer questions via pop-up menus, and perhaps none at all (see the Note section below). Hence, they place more faith in the user to specify the additional arguments correctly. See the files in the FAiR/tests directory for many examples of setting up models the hard way without resorting to the pop-up menu system. You can stop reading this help page now if you are content with the pop-up menus.

If only "Omega" is specified, an object of restrictions.independent-class will emerge and has no common factors. $Omega$ is the only free parameter to estimate, which is only useful in constructing a null model to calculate some fit indices for another model (and all of this would normally be handled automatically by model_comparison anyway). If "Omega" is specified along with other arguments, then this object of parameter.scale-class is merely passed along and will become a slot of the resulting object that inherits from restrictions-class.

If "beta" is specified, but not "Phi" or "Delta", an object of restrictions.orthonormal-class will emerge, which is appropriate for EFA where the upper triangle of $beta$ contains all zeros. If one prefers the maximum-likelihood discrepancy function, there is a faster EFA algorithm that makes the assumption that $beta' Theta^-1 beta$ is diagonal, which can be brought about by specifying model = "EFA" and discrepancy = "MLE" in the call to make_restrictions using the first method in the Usage section above. Doing so will produce an object of restrictions.factanal-class, whose other methods will reproduce the behavior of factanal.

If both "beta" and "Phi" are specified, but not "Delta", an object of restrictions.1storder-class will emerge, which is appropriate for CFA or SEFA when there are no second-order factors, implying that $Phi$ has no structure, other than that required of a correlation matrix. Whether the model is a SEFA depends on whether "beta" inherits from parameter.coef.SEFA-class.

If both "beta" and "Delta" are specified, but not "Xi", an object of restrictions.general-class will emerge, which is appropriate for CFA or SEFA with exactly one second-order factor. The off-diagonals of $Phi$ are $Delta Delta'$. Whether the model is SEFA (at level one) depends on whether "beta" inherits from parameter.coef.SEFA-class and "Delta" cannot inherit from parameter.coef.SEFA-class.

If "beta", "Delta", and "Xi" are specified, an object of restrictions.2ndorder-class will emerge, which is appropriate for CFA or SEFA with multiple second-order factors. Whether this two-level model is SEFA depends on whether "beta" and / or "Delta" inherit from parameter.coef.SEFA-class.

References

Browne, M.W. (1984), Asymptotically distribution-free methods for the analysis of covariance structures, British Journal of Mathematical and Statistical Psychology, 37, 62--83.

Cudeck, R. (1989), Analysis of correlation matrices using covariance structure models, Psychological Bulletin, 105 317--327.

Krane, W. R., and McDonald, R. P. (1978). Scale invariance and the factor analysis of covariance matrices. British Journal of Mathematical and Statistical Psychology, 31, 218–-228.

Yates, A. (1987) Multivariate Exploratory Data Analysis: A Perspective on Exploratory Factor Analysis. State University of New York Press.

See Also

Factanal and restrictions-class

Examples

Run this code
man <- make_manifest(covmat = Harman74.cor)

## Not run: 
# ## Here is the easy way to set up a two-level SEFA model using pop-up menus
# res <- make_restrictions(manifest = man, factors = c(5,2), model = "SEFA")
# ## End(Not run)

## Here is the hard way to set up a two-level SEFA model, 
## which eschews the pop-up menus; do NOT do this without good reason.
## There is an EFA example in ?Rotate
## There is a  CFA example in ?restrictions2RAM
## There is an example with equality restrictions in ?equality_restriction-class

factors <- c(5,2)
beta <- matrix(NA_real_, nrow = nrow(cormat(man)), ncol = factors[1])
rownames(beta) <- rownames(cormat(man))
free <- is.na(beta)
beta <- new("parameter.coef.SEFA", x = beta, free = free, num_free = sum(free))

Delta <- matrix(NA_real_, nrow = factors[1], ncol = factors[2])
rownames(Delta) <- paste("F",  1:factors[1], sep = "")
free  <- is.na(Delta)
Delta <- new("parameter.coef.SEFA", x = Delta, free = free, num_free = sum(free))

Xi <- diag(2)
free <- lower.tri(Xi)
## For fun, require the second-order factors to be positively correlated
uppers <- lowers <- Xi
lowers[2,1] <- 0
uppers[2,1] <- 1
Domains <- array(cbind(lowers, uppers), c(dim(Xi), 2))
Xi <- new("parameter.cormat", x = Xi, free = free, num_free = sum(free),
           Domains = Domains)

res <- make_restrictions(manifest = man, beta = beta, Delta = Delta, Xi = Xi)
show(res)

Run the code above in your browser using DataLab