02make_restrictions: Make an object of class "restrictions"

Description Usage Arguments Details Value Note Author(s) References See Also Examples

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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
## S4 method for signature 
## 'manifest.basic,missing,missing,missing,missing,missing'
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.

Details

Let the factor analysis model in the population be

Sigma = Omega(beta Phi beta' + 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' + 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.

Value

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

Note

In order to enforce inequality restrictions, it is necessary to use a genetic algorithm for lexical optimization (see genoud). Lexcial optimization requires a sequence of piecewise functions, each of which evaluates whether the restriction is satisfied, and an ultimate continuous function, which in this case is a discrepancy function (see Browne (1984)).

In normal usage, the constraints would be specified in response to pop-up menus. In abnormal usage, the pop-up menus can be circumvented by specifying the constraints via the criteria argument, whose elements are user-definied functions or character strings naming constraint functions, which are discussed in more detail below. The primary situation where the pop-up menus must be avoided is when you cannot rely on user-intervention, such as (some types of) Monte Carlo simulations, replication scripts, examples in these documentation pages, the files in FAiR/tests directory of the source code, etc. Conversely, there are templates to do virtually anything without resorting to the pop-up menus in the FAiR/tests directory and anyone who is interested should look there. Note also that when doing simulations, you should almost certainly be setting the seeds argument for various functions to NULL at every opportunity or your simulations will be invalid.

The discrepancy function is named by the "discrepancy" argument and is automatically appended to serve as the ultimate lexical criterion and should not be explicitly specified in criteria under any circumstances.The default behavior of the "discrepancy" argument depends on the exact class of the the manifest argument. If manifest inherits from "manifest.data" or is of class "manifest.basic.userW", the default discrepancy function is Browne's (1984) asymptotically distribution-free ("ADF") discrepancy function (in certain cases the weight matrix for the ADF discrepancy function is diagonal, which is often refered to as “diagonally weighted least squares”). Otherwise, this argument will default to "MLE", which assumes the manifest variables are distributed multivariate normal.

Both "ELLIPTICAL" and "HK" are discrepancy functions that put further structure on the (inverse) weight matrix used by the "ADF" discrepancy function, where the former assumes there is a single kurtosis parameter and the latter assumes a different kurtosis for each manifest variable. The "SHK" discrepancy function differs from the "HK" discrepancy function in that the sample kurtosis estimates are shrunk towards the median kurtosis estimate using the same idea as in the cov.shrink shrinkage estimator of variance in the suggested corpcor package.

If method = "YWLS", Yates' (1987 p.229) weighted least squares “discrepancy” function is used, which does not satisfy Browne's (1984) definition of a discrepancy function. This function has never received much scrutiny and is included in FAiR so that it can be fully evaluated. However, it does not lend itself to calculating standard errors or test statistics, and in limited testing seems prone to finding a solution that is geared more toward minimizing the weights than minimizing the squared residuals. Note that it also differs from the way in which “weighted least squares” is typically used in the factor analysis literature and in particular the LISREL program. “Weighted least squares” in LISREL essentially corresponds to "ADF" in FAiR.

User-defined functions can be passed as elements of criteria and will be called in the environment of the important but not exported function FAiR:::FAiR_lexical_driver, which is defined in FAiR/R/Utils.R. If criteria is a list that includes character strings, they should be names of one or more of the “canned” functions in the following table. Some of these functions have additional arguments that can be specified as elements of methodArgs to avoid seeing a pop-up menu asking for them. See the vignette for formal definitions of these restrictions and methodArgs.

name methodArgs reminder of what function does
"ranks_rows_XXX" row_ranks row-wise ordering constraints
"ranks_cols_XXX" col_ranks column-wise ordering constraints
"indicators_XXX" indicators designate which is the best indicator of a factor
"evRF_XXX" none restrict effective variance of reference factors
"evPF_XXX" none restrict effective variance of primary factors
"h2_over_FC_XXX" none communalities >= factor contributions
"no_neg_suppressors_XXX" FC_threshold no negative suppressors
"gv_XXX" none generalized variance of primary <= reference factors
"distinguishability_XXX" none best indicators have no negative suppressors
"cohyperplanarity_XXX" none hard to explain in this table
"dist_cols_XXX" cutpoint minimum binary distance between columns
"volume_1st" none det(R) >= det(S)
"block_XXX" blockers force coeffients to be non-zero in SEFA

"XXX" can be either "1st" or "2nd" to indicate that the restriction should be applied at the first or second level of a model if there are two levels. However, volume_1st is defined only at the first level of the model. If, for example, one wanted to place row-wise restrictions on the order of the factor contributions at level one and level two of a model, then append "_1st" and "_2nd" to the corresponding elements of methodArgs.

Author(s)

Ben Goodrich

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<e2><80><93>-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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
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)

FAiR documentation built on May 29, 2017, 6:08 p.m.