Factor Analysis Action Set

Principal Factor Analysis

This section contains PROC CAS code.

Note: Input data must be accessible in your CAS session, either as a CAS table or as a transient-scope table. A CAS table has a two-level name: the first level is your CAS engine libref, and the second level is the table name. You refer to this table in the CAS procedure by specifying only the second level. For more information about two-level names, see Chapter 2, Shared Concepts. A transient-scope table is called directly from the action and exists in memory for the duration of the action. For more information about accessing data, see SAS Viya: System Programming Guide. For more information about PROC CAS and programming in CASL, see SAS Cloud Analytic Services: CASL Programmer’s Guide and SAS Cloud Analytic Services: CASL Reference.

This example uses the socioeconomics data set that is described in the examples for the FACTOR procedure in SAS/STAT software. This data set contains five variables, which represent total population (Population), median years of school (School), total employment (Employment), miscellaneous professional services (Services), and median house value (HouseValue). Each observation represents one of twelve census tracts in the Los Angeles Standard Metropolitan Statistical Area.

To create the socioeconomics data table in your CAS session, you can modify the DATA step that is used to create the data set to create the data table in your CAS engine libref. For this example, it is assumed that your CAS engine libref is named mycas, but you can substitute any appropriately defined CAS engine libref.

"Principal Factor Analysis (SAS/STAT User's Guide)" and "Maximum Likelihood Factor Analysis (SAS/STAT User's Guide)" in Chapter 44, The FACTOR Procedure (SAS/STAT User's Guide), show that the socioeconomics data set is well described by a two-factor model. The following code uses the faExtract action to perform a principal factor analysis to extract two factors:

proc cas;
factorAnalysis.faExtract /
    method={name="principal"},
    nFactors={2},
    reorder="true",
    rotate={type="promax"},
    table="socioeconomics";
run;

When you use the faExtract action, you must specify values for the table and nFactors parameters. You specify the input data table to use for the analysis in the table parameter. You use the nFactors parameter to specify the number of factors to be extracted in the analysis. In this example, you use the method parameter to request principal factor extraction. The faExtract action uses squared multiple correlations by default to estimate the prior communalities for an analysis. You can use the priors parameter to specify alternative prior communality estimates.

The factors that are initially extracted by this method are orthogonal. To facilitate the interpretation of these factors, you use the rotate parameter to request factor rotation by the promax method. The promax rotation first computes an orthogonal varimax prerotation by default, which is followed by an oblique Procrustes rotation. You can use the prerotate parameter to specify a different prerotation method, which can be either orthogonal or oblique.

Finally, you specify the reorder parameter so that the rows of the various factor matrices are ordered in such a way that variables whose highest absolute loading is on the first factor are displayed first, followed by variables whose highest absolute loading is on the second factor, and so on.

The first outputs that the faExtract action prints are the "Model Information" table and a table that summarizes the number of observations in the input data table. These are shown in Output 10.3.1. Together, these tables summarize important information about the input data that are analyzed as well as the primary analysis parameters that you specified. Next, the "Simple Statistics" table in Output 10.3.2 summarizes the means and standard deviations of the analysis variables.

Output 10.3.1: Model Information and Number of Observations

Results from factorAnalysis.faExtract

Model Information
Data SourceSOCIOECONOMICS
Data TypeRaw
Prior CommunalitiesSquared Multiple Correlations
Factor ExtractionPrincipal Factor Method
Factor RotationPromax

Number of Observations Read12
Number of Observations Used12


Output 10.3.2: Simple Statistics

Simple Statistics
VariableMeanStandard
Deviation
Population6241.666673439.99427
School11.441671.78654
Employment2333.333331241.21153
Services120.83333114.92751
HouseValue170006367.53128


The prior communality estimates are shown in the "Prior Communality Estimates" table in Output 10.3.3. The prior communalities represent initial estimates of the common variance for each analysis variable. (For more information about communalities and common variance, see the section The Common Factor Model.) The prior communalities are used to compute the reduced correlation matrix. The reduced correlation matrix is the observed correlation matrix for the analysis variables in which the diagonal entries of that matrix are replaced by the prior communalities.

Output 10.3.3: Prior Communalities

Results from factorAnalysis.faExtract

Prior Communality Estimates
PopulationSchoolEmploymentServicesHouseValue
0.968591600.822285140.969180820.785724400.84701921


Next, the eigenvalues of the reduced correlation matrix are computed. These eigenvalues are summarized in the "Preliminary Eigenvalues" table in Output 10.3.4. In this example, the first two largest positive eigenvalues of the reduced correlation matrix account for 101.31% of the common variance. This is possible because the reduced correlation matrix, in general, is not necessarily positive definite, and negative eigenvalues for the matrix are possible. A pattern like this adds further support to the assumption that you might not need more than two common factors in this analysis.

Output 10.3.4: Preliminary Eigenvalues

Eigenvalues of the Reduced Correlation Matrix: Total = 4.39280116 Average = 0.87856023
 EigenvalueDifferenceProportionCumulative
12.7343011.0182320.62250.6225
21.7160691.6765060.39071.0131
30.0395630.0640860.00901.0221
4-0.0245230.048084-0.00561.0165
5-0.072608 -0.01651.0000


The principal factor pattern with the two extracted factors is displayed in Output 10.3.5. The Services variable has the largest loading on the first factor, and the Population variable has the smallest. The Population and Employment variables have large positive loadings on the second factor, and the HouseValue and School variables have large negative loadings.

Output 10.3.5: Factor Pattern

Factor Pattern
 Factor1Factor2
Services0.87899-0.15847
HouseValue0.74215-0.57806
Employment0.714470.67936
School0.71370-0.55515
Population0.625330.76621


The variance explained by the extracted factors is summarized in Output 10.3.6, and the final communality estimates are shown in Output 10.3.7.

Output 10.3.6: Variance Explained (Initial Solution)

Variance Explained by Each
Factor
Factor1Factor2
2.73430081.7160687


Output 10.3.7: Final Communalities (Initial Solution)

Final Communality Estimates: Total = 4.450370
PopulationSchoolEmploymentServicesHouseValue
0.978113340.817563870.971999280.797743040.88494998


Next, you want to rotate the factor pattern such that most variables would have zero loadings on most factors. In this example, you specified a promax rotation with a varimax prerotation. To yield the prerotated factor pattern, the initial factor loading matrix is post-multiplied by an orthogonal transformation matrix that satisfies the varimax criterion. This orthogonal transformation matrix, as well as the varimax-rotated factor pattern, is shown in Output 10.3.8. The rotation leads to small loadings of Population and Employment on the first factor and small loadings of HouseValue and School on the second factor. Services appears to have a larger loading on the first factor than it has on the second factor, although both loadings are substantial. Hence, Services appears to be factorially complex.

The reorder parameter helps you see the variable clusters clearly in the factor pattern. The first factor is associated more with the first three variables: HouseValue, School, and Services. The second factor is associated more with the last two variables: Population and Employment. For orthogonal factor solutions such as the current varimax-rotated solution, you can also interpret the values in the factor loading matrix as correlations. For example, HouseValue and Factor 1 have a high correlation of 0.94, whereas Population and Factor 1 have a low correlation of 0.02.

Output 10.3.8: Orthogonal Transformation and Factor Pattern (Prerotated Solution)

Results from factorAnalysis.faExtract

Orthogonal Transformation Matrix
 12
10.788950.61446
2-0.614460.78895

Rotated Factor Pattern
 Factor1Factor2
HouseValue0.94072-0.00004
School0.904190.00055
Services0.790850.41509
Population0.022550.98874
Employment0.146250.97499


The variance explained by the prerotated factors, as well as the final communality estimates, is shown in Output 10.3.9. The variance explained by the factors is more evenly distributed in the varimax-rotated solution, as compared to that of the unrotated solution. Indeed, this is a typical fact for any kind of factor rotation. In the current example, before the varimax rotation, the two factors explain 2.73 and 1.72, respectively, of the common variance (see Output 10.3.6). After the varimax rotation, the two rotated factors explain 2.35 and 2.10, respectively, of the common variance. However, the total variance explained by the factors remains unchanged after the varimax rotation. This invariance property is also observed for the communalities of the variables after the rotation, as you can see by comparing the current communality estimates in Output 10.3.6 to those in Output 10.3.7.

Output 10.3.9: Variance Explained and Final Communalities (Prerotated Solution)

Variance Explained by Each
Factor
Factor1Factor2
2.34985672.1005128

Final Communality Estimates: Total = 4.450370
PopulationSchoolEmploymentServicesHouseValue
0.978113340.817563870.971999280.797743040.88494998


Some factor analysts believe that common factors are seldom orthogonal. Thus an obliquely rotated factor solution might be more desirable, or at least it should be attempted. In the current example, you used the rotate parameter to request a promax rotation, which allows factors to be correlated. Output 10.3.10 shows the Procrustes target, followed by the display of the Procrustes transformation matrix. This is the matrix that transforms the varimax factor pattern so that the rotated pattern is as close as possible to the Procrustes target, which is created by exponentiating the elements of the prerotated factor pattern (while keeping the signs of the values). However, because the variances of factors must be fixed at 1 during the oblique transformation, a normalized version of the Procrustes transformation matrix is the one that is actually used in the transformation. This normalized transformation matrix is shown at the bottom of Output 10.3.10.

Output 10.3.10: Promax Rotation: Procrustes Target and Transformation Matrices

Results from factorAnalysis.faExtract

Target Matrix for Procrustes Transformation
 Factor1Factor2
HouseValue1.00000-0.00000
School1.000000.00000
Services0.694210.10045
Population0.000011.00000
Employment0.003260.96793

Procrustes Transformation Matrix
 12
11.04117-0.09865
2-0.105720.96303

Normalized Oblique Transformation
Matrix
 12
10.738030.54202
2-0.705550.86528


Using this transformation matrix leads to the promax-rotated factor solution, as shown in Output 10.3.11. After the promax rotation, the factors are no longer uncorrelated. As shown in the "Interfactor Correlations" table, the correlation of the two factors is now 0.20. In the unrotated and the varimax solutions, the two factors are not correlated.

Output 10.3.11: Promax Rotation: Factor Correlations and Rotated Factor Pattern

Interfactor Correlations
 Factor1Factor2
Factor11.000000.20188
Factor20.201881.00000

Rotated Factor Pattern (Standardized
Regression Coefficients)
 Factor1Factor2
HouseValue0.95558-0.09792
School0.91842-0.09352
Services0.760530.33932
Population-0.079081.00192
Employment0.047990.97509


Unlike orthogonal factor solutions, where you can interpret the factor loadings as correlations between variables and factors, in oblique factor solutions such as the promax solution, you have to turn to the factor structure matrix to examine the correlations between variables and factors. Output 10.3.12 shows the factor structures for the promax-rotated solution. In this example, the factor structure matrix reflects a pattern similar to that of the factor pattern matrix shown in Output 10.3.11. The critical difference is that you can have the correlation interpretation only by using the factor structure matrix. For example, in the factor structure matrix, the correlation between Population and Factor 2 is 0.986. The corresponding value shown in the factor pattern matrix is 1.002, which you certainly cannot interpret as a correlation coefficient.

Output 10.3.12: Factor Structure

Factor Structure (Correlations)
 Factor1Factor2
HouseValue0.935820.09500
School0.899540.09189
Services0.829030.49286
Population0.123190.98596
Employment0.244840.98478


When factors are correlated, the common variance explained by each factor is not as straightforward as it is in the case when the factors are uncorrelated. The contributions from the other factors must be either eliminated or ignored. Both computations are shown in Output 10.3.13.

When you ignore the other factor, the common variance explained by the promax-rotated factors is 2.45 and 2.20, respectively. In contrast with orthogonal factor solutions (such as the prerotated varimax solution), the variance explained by these promax-rotated factors (ignoring other factors) does not sum to the total communality estimate of 4.45 (see Output 10.3.14).

Also shown in Output 10.3.13 is the "Variance Explained by Each Factor, Eliminating Other Factors" table. The values in this table represent unique variances explained by the factors, partialing out the variances explained by all other factors (or eliminating all other factors, as the table title suggests). In the current example, Factor 1 explains 2.25 of the variable variances, partialing out all variable variances explained by Factor 2.

Output 10.3.13: Variance Explained

Variance Explained by Each
Factor, Ignoring Other Factors
Factor1Factor2
2.44734952.2022803

Variance Explained by Each
Factor, Eliminating Other
Factors
Factor1Factor2
2.24808922.0030200


The communalities of the variables, as shown in Output 10.3.14, do not change from rotation to rotation. They are still the same set of communalities in the initial, varimax-rotated, and promax-rotated solutions. This is a basic fact about factor rotations: they redistribute the variance explained by the factors; the total variance explained by the factors for any variable (that is, the communality of the variable) remains unchanged.

Output 10.3.14: Final Communalities

Final Communality Estimates: Total = 4.450370
PopulationSchoolEmploymentServicesHouseValue
0.978113340.817563870.971999280.797743040.88494998


Principal Factor Analysis

This section contains Lua code that creates the same socioeconomics table and performs the same analysis as shown in the CASL version of this example. For more information about coding in Lua, see Getting Started with SAS Viya for Lua and SAS Viya: System Programming Guide.

Because this example uses simulated data that are produced from DATA step code, you can submit the runCode action on your Lua client to create the simulated data in your CAS session.

This example uses the socioeconomics data set that is described in the examples for the FACTOR procedure in SAS/STAT software. This data set contains five variables, which represent total population (Population), median years of school (School), total employment (Employment), miscellaneous professional services (Services), and median house value (HouseValue). Each observation represents one of twelve census tracts in the Los Angeles Standard Metropolitan Statistical Area.

To run this example code, you must make the socioeconomics data accessible to the CAS server. One way to do this is to convert the socioeconomics data set from the PROC FACTOR documentation to a comma-separated-value (CSV) file and then load the CSV file into CAS.

"Principal Factor Analysis (SAS/STAT User's Guide)" and "Maximum Likelihood Factor Analysis (SAS/STAT User's Guide)" in Chapter 44, The FACTOR Procedure (SAS/STAT User's Guide), show that the socioeconomics data set is well described by a two-factor model. The following code uses the faExtract action to perform a principal factor analysis to extract two factors:

s:loadactionset{actionset="factorAnalysis"}
s:factorAnalysis_faExtract{
table='socioeconomics',
nFactors={2},
method={name='principal'},
rotate={type='promax'},
reorder=true
}

When you use the faExtract action, you must specify values for the table and nFactors parameters. You specify the input data table to use for the analysis in the table parameter. You use the nFactors parameter to specify the number of factors to be extracted in the analysis. In this example, you use the method parameter to request principal factor extraction. The faExtract action uses squared multiple correlations by default to estimate the prior communalities for an analysis. You can use the priors parameter to specify alternative prior communality estimates.

The factors that are initially extracted by this method are orthogonal. To facilitate the interpretation of these factors, you use the rotate parameter to request factor rotation by the promax method. The promax rotation first computes an orthogonal varimax prerotation by default, which is followed by an oblique Procrustes rotation. You can use the prerotate parameter to specify a different prerotation method, which can be either orthogonal or oblique.

Finally, you specify the reorder parameter so that the rows of the various factor matrices are ordered in such a way that variables whose highest absolute loading is on the first factor are displayed first, followed by variables whose highest absolute loading is on the second factor, and so on.

The first outputs that the faExtract action prints are the "Model Information" table and a table that summarizes the number of observations in the input data table. These are shown in Output 10.3.15. Together, these tables summarize important information about the input data that are analyzed as well as the primary analysis parameters that you specified. Next, the "Simple Statistics" table in Output 10.3.16 summarizes the means and standard deviations of the analysis variables.

Output 10.3.15: Model Information and Number of Observations

RowIdDescriptioncValueValue
TABLEData SourceSOCIOECONOMICS.
TYPEData TypeRaw.
PRIORSPrior CommunalitiesSquared Multiple Correlations.
EXTRACTFactor ExtractionPrincipal Factor Method.
ROTATEFactor RotationPromax.

RowIdDescriptionValue
NREADNumber of Observations Read12
NUSEDNumber of Observations Used12


Output 10.3.16: Simple Statistics

VariableMeanStdDev
Population6241.666673439.99427
School11.441671.78654
Employment2333.333331241.21153
Services120.83333114.92751
HouseValue170006367.53128


The prior communality estimates are shown in the "Prior Communality Estimates" table in Output 10.3.17. The prior communalities represent initial estimates of the common variance for each analysis variable. (For more information about communalities and common variance, see the section The Common Factor Model.) The prior communalities are used to compute the reduced correlation matrix. The reduced correlation matrix is the observed correlation matrix for the analysis variables in which the diagonal entries of that matrix are replaced by the prior communalities.

Output 10.3.17: Prior Communalities

PopulationSchoolEmploymentServicesHouseValue
0.968591600.822285140.969180820.785724400.84701921


Next, the eigenvalues of the reduced correlation matrix are computed. These eigenvalues are summarized in the "Preliminary Eigenvalues" table in Output 10.3.18. In this example, the first two largest positive eigenvalues of the reduced correlation matrix account for 101.31% of the common variance. This is possible because the reduced correlation matrix, in general, is not necessarily positive definite, and negative eigenvalues for the matrix are possible. A pattern like this adds further support to the assumption that you might not need more than two common factors in this analysis.

Output 10.3.18: Preliminary Eigenvalues

NumberEigenvalueDifferenceProportionCumulative
12.7343011.0182320.62250.6225
21.7160691.6765060.39071.0131
30.0395630.0640860.00901.0221
4-0.0245230.048084-0.00561.0165
5-0.072608_-0.01651.0000


The principal factor pattern with the two extracted factors is displayed in Output 10.3.19. The Services variable has the largest loading on the first factor, and the Population variable has the smallest. The Population and Employment variables have large positive loadings on the second factor, and the HouseValue and School variables have large negative loadings.

Output 10.3.19: Factor Pattern

VariableFactor1Factor2
Services0.87899-0.15847
HouseValue0.74215-0.57806
Employment0.714470.67936
School0.71370-0.55515
Population0.625330.76621


The variance explained by the extracted factors is summarized in Output 10.3.20, and the final communality estimates are shown in Output 10.3.21.

Output 10.3.20: Variance Explained (Initial Solution)

Factor1Factor2Solution
2.73430081.7160687Initial


Output 10.3.21: Final Communalities (Initial Solution)

PopulationSchoolEmploymentServicesHouseValueSolution
0.978113340.817563870.971999280.797743040.88494998Initial


Next, you want to rotate the factor pattern such that most variables would have zero loadings on most factors. In this example, you specified a promax rotation with a varimax prerotation. To yield the prerotated factor pattern, the initial factor loading matrix is post-multiplied by an orthogonal transformation matrix that satisfies the varimax criterion. This orthogonal transformation matrix, as well as the varimax-rotated factor pattern, is shown in Output 10.3.22. The rotation leads to small loadings of Population and Employment on the first factor and small loadings of HouseValue and School on the second factor. Services appears to have a larger loading on the first factor than it has on the second factor, although both loadings are substantial. Hence, Services appears to be factorially complex.

The reorder parameter helps you see the variable clusters clearly in the factor pattern. The first factor is associated more with the first three variables: HouseValue, School, and Services. The second factor is associated more with the last two variables: Population and Employment. For orthogonal factor solutions such as the current varimax-rotated solution, you can also interpret the values in the factor loading matrix as correlations. For example, HouseValue and Factor 1 have a high correlation of 0.94, whereas Population and Factor 1 have a low correlation of 0.02.

Output 10.3.22: Orthogonal Transformation and Factor Pattern (Prerotated Solution)

RowLabel12
10.788950.61446
2-0.614460.78895

VariableFactor1Factor2
HouseValue0.94072-0.00004
School0.904190.00055
Services0.790850.41509
Population0.022550.98874
Employment0.146250.97499


The variance explained by the prerotated factors, as well as the final communality estimates, is shown in Output 10.3.23. The variance explained by the factors is more evenly distributed in the varimax-rotated solution, as compared to that of the unrotated solution. Indeed, this is a typical fact for any kind of factor rotation. In the current example, before the varimax rotation, the two factors explain 2.73 and 1.72, respectively, of the common variance (see Output 10.3.20). After the varimax rotation, the two rotated factors explain 2.35 and 2.10, respectively, of the common variance. However, the total variance explained by the factors remains unchanged after the varimax rotation. This invariance property is also observed for the communalities of the variables after the rotation, as you can see by comparing the current communality estimates in Output 10.3.20 to those in Output 10.3.21.

Output 10.3.23: Variance Explained and Final Communalities (Prerotated Solution)

Factor1Factor2Solution
2.34985672.1005128Prerotated

PopulationSchoolEmploymentServicesHouseValueSolution
0.978113340.817563870.971999280.797743040.88494998Prerotated


Some factor analysts believe that common factors are seldom orthogonal. Thus an obliquely rotated factor solution might be more desirable, or at least it should be attempted. In the current example, you used the rotate parameter to request a promax rotation, which allows factors to be correlated. Output 10.3.24 shows the Procrustes target, followed by the display of the Procrustes transformation matrix. This is the matrix that transforms the varimax factor pattern so that the rotated pattern is as close as possible to the Procrustes target, which is created by exponentiating the elements of the prerotated factor pattern (while keeping the signs of the values). However, because the variances of factors must be fixed at 1 during the oblique transformation, a normalized version of the Procrustes transformation matrix is the one that is actually used in the transformation. This normalized transformation matrix is shown at the bottom of Output 10.3.24.

Output 10.3.24: Promax Rotation: Procrustes Target and Transformation Matrices

VariableFactor1Factor2
HouseValue1.00000-0.00000
School1.000000.00000
Services0.694210.10045
Population0.000011.00000
Employment0.003260.96793

RowLabel12
11.04117-0.09865
2-0.105720.96303

RowLabel12
10.738030.54202
2-0.705550.86528


Using this transformation matrix leads to the promax-rotated factor solution, as shown in Output 10.3.25. After the promax rotation, the factors are no longer uncorrelated. As shown in the "Interfactor Correlations" table, the correlation of the two factors is now 0.20. In the unrotated and the varimax solutions, the two factors are not correlated.

Output 10.3.25: Promax Rotation: Factor Correlations and Rotated Factor Pattern

RowNameFactor1Factor2
Factor11.000000.20188
Factor20.201881.00000

VariableFactor1Factor2
HouseValue0.95558-0.09792
School0.91842-0.09352
Services0.760530.33932
Population-0.079081.00192
Employment0.047990.97509


Unlike orthogonal factor solutions, where you can interpret the factor loadings as correlations between variables and factors, in oblique factor solutions such as the promax solution, you have to turn to the factor structure matrix to examine the correlations between variables and factors. Output 10.3.26 shows the factor structures for the promax-rotated solution. In this example, the factor structure matrix reflects a pattern similar to that of the factor pattern matrix shown in Output 10.3.25. The critical difference is that you can have the correlation interpretation only by using the factor structure matrix. For example, in the factor structure matrix, the correlation between Population and Factor 2 is 0.986. The corresponding value shown in the factor pattern matrix is 1.002, which you certainly cannot interpret as a correlation coefficient.

Output 10.3.26: Factor Structure

VariableFactor1Factor2
HouseValue0.935820.09500
School0.899540.09189
Services0.829030.49286
Population0.123190.98596
Employment0.244840.98478


When factors are correlated, the common variance explained by each factor is not as straightforward as it is in the case when the factors are uncorrelated. The contributions from the other factors must be either eliminated or ignored. Both computations are shown in Output 10.3.27.

When you ignore the other factor, the common variance explained by the promax-rotated factors is 2.45 and 2.20, respectively. In contrast with orthogonal factor solutions (such as the prerotated varimax solution), the variance explained by these promax-rotated factors (ignoring other factors) does not sum to the total communality estimate of 4.45 (see Output 10.3.28).

Also shown in Output 10.3.27 is the "Variance Explained by Each Factor, Eliminating Other Factors" table. The values in this table represent unique variances explained by the factors, partialing out the variances explained by all other factors (or eliminating all other factors, as the table title suggests). In the current example, Factor 1 explains 2.25 of the variable variances, partialing out all variable variances explained by Factor 2.

Output 10.3.27: Variance Explained

Factor1Factor2Solution
2.44734952.2022803Rotated

Factor1Factor2Solution
2.44734952.2022803Rotated


The communalities of the variables, as shown in Output 10.3.28, do not change from rotation to rotation. They are still the same set of communalities in the initial, varimax-rotated, and promax-rotated solutions. This is a basic fact about factor rotations: they redistribute the variance explained by the factors; the total variance explained by the factors for any variable (that is, the communality of the variable) remains unchanged.

Output 10.3.28: Final Communalities

PopulationSchoolEmploymentServicesHouseValueSolution
0.978113340.817563870.971999280.797743040.88494998Rotated


Principal Factor Analysis

This section contains Python code that creates the same socioeconomics table and performs the same analysis as shown in the CASL version of this example. For more information about coding in Python, see Getting Started with SAS Viya for Python and SAS Viya: System Programming Guide.

Because this example uses simulated data that are produced from DATA step code, you can submit the runCode action on your Python client to create the simulated data in your CAS session.

This example uses the socioeconomics data set that is described in the examples for the FACTOR procedure in SAS/STAT software. This data set contains five variables, which represent total population (Population), median years of school (School), total employment (Employment), miscellaneous professional services (Services), and median house value (HouseValue). Each observation represents one of twelve census tracts in the Los Angeles Standard Metropolitan Statistical Area.

To run this example code, you must make the socioeconomics data accessible to the CAS server. One way to do this is to convert the socioeconomics data set from the PROC FACTOR documentation to a comma-separated-value (CSV) file and then load the CSV file into CAS.

"Principal Factor Analysis (SAS/STAT User's Guide)" and "Maximum Likelihood Factor Analysis (SAS/STAT User's Guide)" in Chapter 44, The FACTOR Procedure (SAS/STAT User's Guide), show that the socioeconomics data set is well described by a two-factor model. The following code uses the faExtract action to perform a principal factor analysis to extract two factors:

s.loadactionset(actionset='factorAnalysis')
s.factoranalysis.faextract(
    method=dict(name='principal'),
    nFactors=[2],
    reorder='true',
    rotate=dict(type='promax'),
    table='socioeconomics')

When you use the faExtract action, you must specify values for the table and nFactors parameters. You specify the input data table to use for the analysis in the table parameter. You use the nFactors parameter to specify the number of factors to be extracted in the analysis. In this example, you use the method parameter to request principal factor extraction. The faExtract action uses squared multiple correlations by default to estimate the prior communalities for an analysis. You can use the priors parameter to specify alternative prior communality estimates.

The factors that are initially extracted by this method are orthogonal. To facilitate the interpretation of these factors, you use the rotate parameter to request factor rotation by the promax method. The promax rotation first computes an orthogonal varimax prerotation by default, which is followed by an oblique Procrustes rotation. You can use the prerotate parameter to specify a different prerotation method, which can be either orthogonal or oblique.

Finally, you specify the reorder parameter so that the rows of the various factor matrices are ordered in such a way that variables whose highest absolute loading is on the first factor are displayed first, followed by variables whose highest absolute loading is on the second factor, and so on.

The first outputs that the faExtract action prints are the "Model Information" table and a table that summarizes the number of observations in the input data table. These are shown in Output 10.3.29. Together, these tables summarize important information about the input data that are analyzed as well as the primary analysis parameters that you specified. Next, the "Simple Statistics" table in Output 10.3.30 summarizes the means and standard deviations of the analysis variables.

Output 10.3.29: Model Information and Number of Observations

RowIdDescriptioncValueValue
TABLEData SourceSOCIOECONOMICS.
TYPEData TypeRaw.
PRIORSPrior CommunalitiesSquared Multiple Correlations.
EXTRACTFactor ExtractionPrincipal Factor Method.
ROTATEFactor RotationPromax.

RowIdDescriptionValue
NREADNumber of Observations Read12
NUSEDNumber of Observations Used12


Output 10.3.30: Simple Statistics

VariableMeanStdDev
Population6241.666673439.99427
School11.441671.78654
Employment2333.333331241.21153
Services120.83333114.92751
HouseValue170006367.53128


The prior communality estimates are shown in the "Prior Communality Estimates" table in Output 10.3.31. The prior communalities represent initial estimates of the common variance for each analysis variable. (For more information about communalities and common variance, see the section The Common Factor Model.) The prior communalities are used to compute the reduced correlation matrix. The reduced correlation matrix is the observed correlation matrix for the analysis variables in which the diagonal entries of that matrix are replaced by the prior communalities.

Output 10.3.31: Prior Communalities

PopulationSchoolEmploymentServicesHouseValue
0.968591600.822285140.969180820.785724400.84701921


Next, the eigenvalues of the reduced correlation matrix are computed. These eigenvalues are summarized in the "Preliminary Eigenvalues" table in Output 10.3.32. In this example, the first two largest positive eigenvalues of the reduced correlation matrix account for 101.31% of the common variance. This is possible because the reduced correlation matrix, in general, is not necessarily positive definite, and negative eigenvalues for the matrix are possible. A pattern like this adds further support to the assumption that you might not need more than two common factors in this analysis.

Output 10.3.32: Preliminary Eigenvalues

NumberEigenvalueDifferenceProportionCumulative
12.7343011.0182320.62250.6225
21.7160691.6765060.39071.0131
30.0395630.0640860.00901.0221
4-0.0245230.048084-0.00561.0165
5-0.072608_-0.01651.0000


The principal factor pattern with the two extracted factors is displayed in Output 10.3.33. The Services variable has the largest loading on the first factor, and the Population variable has the smallest. The Population and Employment variables have large positive loadings on the second factor, and the HouseValue and School variables have large negative loadings.

Output 10.3.33: Factor Pattern

VariableFactor1Factor2
Services0.87899-0.15847
HouseValue0.74215-0.57806
Employment0.714470.67936
School0.71370-0.55515
Population0.625330.76621


The variance explained by the extracted factors is summarized in Output 10.3.34, and the final communality estimates are shown in Output 10.3.35.

Output 10.3.34: Variance Explained (Initial Solution)

Factor1Factor2Solution
2.73430081.7160687Initial


Output 10.3.35: Final Communalities (Initial Solution)

PopulationSchoolEmploymentServicesHouseValueSolution
0.978113340.817563870.971999280.797743040.88494998Initial


Next, you want to rotate the factor pattern such that most variables would have zero loadings on most factors. In this example, you specified a promax rotation with a varimax prerotation. To yield the prerotated factor pattern, the initial factor loading matrix is post-multiplied by an orthogonal transformation matrix that satisfies the varimax criterion. This orthogonal transformation matrix, as well as the varimax-rotated factor pattern, is shown in Output 10.3.36. The rotation leads to small loadings of Population and Employment on the first factor and small loadings of HouseValue and School on the second factor. Services appears to have a larger loading on the first factor than it has on the second factor, although both loadings are substantial. Hence, Services appears to be factorially complex.

The reorder parameter helps you see the variable clusters clearly in the factor pattern. The first factor is associated more with the first three variables: HouseValue, School, and Services. The second factor is associated more with the last two variables: Population and Employment. For orthogonal factor solutions such as the current varimax-rotated solution, you can also interpret the values in the factor loading matrix as correlations. For example, HouseValue and Factor 1 have a high correlation of 0.94, whereas Population and Factor 1 have a low correlation of 0.02.

Output 10.3.36: Orthogonal Transformation and Factor Pattern (Prerotated Solution)

RowLabel12
10.788950.61446
2-0.614460.78895

VariableFactor1Factor2
HouseValue0.94072-0.00004
School0.904190.00055
Services0.790850.41509
Population0.022550.98874
Employment0.146250.97499


The variance explained by the prerotated factors, as well as the final communality estimates, is shown in Output 10.3.37. The variance explained by the factors is more evenly distributed in the varimax-rotated solution, as compared to that of the unrotated solution. Indeed, this is a typical fact for any kind of factor rotation. In the current example, before the varimax rotation, the two factors explain 2.73 and 1.72, respectively, of the common variance (see Output 10.3.34). After the varimax rotation, the two rotated factors explain 2.35 and 2.10, respectively, of the common variance. However, the total variance explained by the factors remains unchanged after the varimax rotation. This invariance property is also observed for the communalities of the variables after the rotation, as you can see by comparing the current communality estimates in Output 10.3.34 to those in Output 10.3.35.

Output 10.3.37: Variance Explained and Final Communalities (Prerotated Solution)

Factor1Factor2Solution
2.34985672.1005128Prerotated

PopulationSchoolEmploymentServicesHouseValueSolution
0.978113340.817563870.971999280.797743040.88494998Prerotated


Some factor analysts believe that common factors are seldom orthogonal. Thus an obliquely rotated factor solution might be more desirable, or at least it should be attempted. In the current example, you used the rotate parameter to request a promax rotation, which allows factors to be correlated. Output 10.3.38 shows the Procrustes target, followed by the display of the Procrustes transformation matrix. This is the matrix that transforms the varimax factor pattern so that the rotated pattern is as close as possible to the Procrustes target, which is created by exponentiating the elements of the prerotated factor pattern (while keeping the signs of the values). However, because the variances of factors must be fixed at 1 during the oblique transformation, a normalized version of the Procrustes transformation matrix is the one that is actually used in the transformation. This normalized transformation matrix is shown at the bottom of Output 10.3.38.

Output 10.3.38: Promax Rotation: Procrustes Target and Transformation Matrices

VariableFactor1Factor2
HouseValue1.00000-0.00000
School1.000000.00000
Services0.694210.10045
Population0.000011.00000
Employment0.003260.96793

RowLabel12
11.04117-0.09865
2-0.105720.96303

RowLabel12
10.738030.54202
2-0.705550.86528


Using this transformation matrix leads to the promax-rotated factor solution, as shown in Output 10.3.39. After the promax rotation, the factors are no longer uncorrelated. As shown in the "Interfactor Correlations" table, the correlation of the two factors is now 0.20. In the unrotated and the varimax solutions, the two factors are not correlated.

Output 10.3.39: Promax Rotation: Factor Correlations and Rotated Factor Pattern

RowNameFactor1Factor2
Factor11.000000.20188
Factor20.201881.00000

VariableFactor1Factor2
HouseValue0.95558-0.09792
School0.91842-0.09352
Services0.760530.33932
Population-0.079081.00192
Employment0.047990.97509


Unlike orthogonal factor solutions, where you can interpret the factor loadings as correlations between variables and factors, in oblique factor solutions such as the promax solution, you have to turn to the factor structure matrix to examine the correlations between variables and factors. Output 10.3.40 shows the factor structures for the promax-rotated solution. In this example, the factor structure matrix reflects a pattern similar to that of the factor pattern matrix shown in Output 10.3.39. The critical difference is that you can have the correlation interpretation only by using the factor structure matrix. For example, in the factor structure matrix, the correlation between Population and Factor 2 is 0.986. The corresponding value shown in the factor pattern matrix is 1.002, which you certainly cannot interpret as a correlation coefficient.

Output 10.3.40: Factor Structure

VariableFactor1Factor2
HouseValue0.935820.09500
School0.899540.09189
Services0.829030.49286
Population0.123190.98596
Employment0.244840.98478


When factors are correlated, the common variance explained by each factor is not as straightforward as it is in the case when the factors are uncorrelated. The contributions from the other factors must be either eliminated or ignored. Both computations are shown in Output 10.3.41.

When you ignore the other factor, the common variance explained by the promax-rotated factors is 2.45 and 2.20, respectively. In contrast with orthogonal factor solutions (such as the prerotated varimax solution), the variance explained by these promax-rotated factors (ignoring other factors) does not sum to the total communality estimate of 4.45 (see Output 10.3.42).

Also shown in Output 10.3.41 is the "Variance Explained by Each Factor, Eliminating Other Factors" table. The values in this table represent unique variances explained by the factors, partialing out the variances explained by all other factors (or eliminating all other factors, as the table title suggests). In the current example, Factor 1 explains 2.25 of the variable variances, partialing out all variable variances explained by Factor 2.

Output 10.3.41: Variance Explained

Factor1Factor2Solution
2.44734952.2022803Rotated

Factor1Factor2Solution
2.44734952.2022803Rotated


The communalities of the variables, as shown in Output 10.3.42, do not change from rotation to rotation. They are still the same set of communalities in the initial, varimax-rotated, and promax-rotated solutions. This is a basic fact about factor rotations: they redistribute the variance explained by the factors; the total variance explained by the factors for any variable (that is, the communality of the variable) remains unchanged.

Output 10.3.42: Final Communalities

PopulationSchoolEmploymentServicesHouseValueSolution
0.978113340.817563870.971999280.797743040.88494998Rotated


Principal Factor Analysis

This section contains R code that creates the same socioeconomics table and performs the same analysis as shown in the CASL version of this example. For more information about coding in R, see Getting Started with SAS Viya for R and SAS Viya: System Programming Guide.

Because this example uses simulated data that are produced from DATA step code, you can submit the runCode action on your R client to create the simulated data in your CAS session.

This example uses the socioeconomics data set that is described in the examples for the FACTOR procedure in SAS/STAT software. This data set contains five variables, which represent total population (Population), median years of school (School), total employment (Employment), miscellaneous professional services (Services), and median house value (HouseValue). Each observation represents one of twelve census tracts in the Los Angeles Standard Metropolitan Statistical Area.

To run this example code, you must make the socioeconomics data accessible to the CAS server. One way to do this is to convert the socioeconomics data set from the PROC FACTOR documentation to a comma-separated-value (CSV) file and then load the CSV file into CAS.

"Principal Factor Analysis (SAS/STAT User's Guide)" and "Maximum Likelihood Factor Analysis (SAS/STAT User's Guide)" in Chapter 44, The FACTOR Procedure (SAS/STAT User's Guide), show that the socioeconomics data set is well described by a two-factor model. The following code uses the faExtract action to perform a principal factor analysis to extract two factors:

m <- cas.builtins.loadActionSet(s, actionset='factorAnalysis')
cas.factorAnalysis.faExtract(s,
    method=list(name='principal'),
    nFactors=c(2),
    reorder='true',
    rotate=list(type='promax'),
    table='socioeconomics')

When you use the faExtract action, you must specify values for the table and nFactors parameters. You specify the input data table to use for the analysis in the table parameter. You use the nFactors parameter to specify the number of factors to be extracted in the analysis. In this example, you use the method parameter to request principal factor extraction. The faExtract action uses squared multiple correlations by default to estimate the prior communalities for an analysis. You can use the priors parameter to specify alternative prior communality estimates.

The factors that are initially extracted by this method are orthogonal. To facilitate the interpretation of these factors, you use the rotate parameter to request factor rotation by the promax method. The promax rotation first computes an orthogonal varimax prerotation by default, which is followed by an oblique Procrustes rotation. You can use the prerotate parameter to specify a different prerotation method, which can be either orthogonal or oblique.

Finally, you specify the reorder parameter so that the rows of the various factor matrices are ordered in such a way that variables whose highest absolute loading is on the first factor are displayed first, followed by variables whose highest absolute loading is on the second factor, and so on.

The first outputs that the faExtract action prints are the "Model Information" table and a table that summarizes the number of observations in the input data table. These are shown in Output 10.3.43. Together, these tables summarize important information about the input data that are analyzed as well as the primary analysis parameters that you specified. Next, the "Simple Statistics" table in Output 10.3.44 summarizes the means and standard deviations of the analysis variables.

Output 10.3.43: Model Information and Number of Observations

RowIdDescriptioncValueValue
TABLEData SourceSOCIOECONOMICS.
TYPEData TypeRaw.
PRIORSPrior CommunalitiesSquared Multiple Correlations.
EXTRACTFactor ExtractionPrincipal Factor Method.
ROTATEFactor RotationPromax.

RowIdDescriptionValue
NREADNumber of Observations Read12
NUSEDNumber of Observations Used12


Output 10.3.44: Simple Statistics

VariableMeanStdDev
Population6241.666673439.99427
School11.441671.78654
Employment2333.333331241.21153
Services120.83333114.92751
HouseValue170006367.53128


The prior communality estimates are shown in the "Prior Communality Estimates" table in Output 10.3.45. The prior communalities represent initial estimates of the common variance for each analysis variable. (For more information about communalities and common variance, see the section The Common Factor Model.) The prior communalities are used to compute the reduced correlation matrix. The reduced correlation matrix is the observed correlation matrix for the analysis variables in which the diagonal entries of that matrix are replaced by the prior communalities.

Output 10.3.45: Prior Communalities

PopulationSchoolEmploymentServicesHouseValue
0.968591600.822285140.969180820.785724400.84701921


Next, the eigenvalues of the reduced correlation matrix are computed. These eigenvalues are summarized in the "Preliminary Eigenvalues" table in Output 10.3.46. In this example, the first two largest positive eigenvalues of the reduced correlation matrix account for 101.31% of the common variance. This is possible because the reduced correlation matrix, in general, is not necessarily positive definite, and negative eigenvalues for the matrix are possible. A pattern like this adds further support to the assumption that you might not need more than two common factors in this analysis.

Output 10.3.46: Preliminary Eigenvalues

NumberEigenvalueDifferenceProportionCumulative
12.7343011.0182320.62250.6225
21.7160691.6765060.39071.0131
30.0395630.0640860.00901.0221
4-0.0245230.048084-0.00561.0165
5-0.072608_-0.01651.0000


The principal factor pattern with the two extracted factors is displayed in Output 10.3.47. The Services variable has the largest loading on the first factor, and the Population variable has the smallest. The Population and Employment variables have large positive loadings on the second factor, and the HouseValue and School variables have large negative loadings.

Output 10.3.47: Factor Pattern

VariableFactor1Factor2
Services0.87899-0.15847
HouseValue0.74215-0.57806
Employment0.714470.67936
School0.71370-0.55515
Population0.625330.76621


The variance explained by the extracted factors is summarized in Output 10.3.48, and the final communality estimates are shown in Output 10.3.49.

Output 10.3.48: Variance Explained (Initial Solution)

Factor1Factor2Solution
2.73430081.7160687Initial


Output 10.3.49: Final Communalities (Initial Solution)

PopulationSchoolEmploymentServicesHouseValueSolution
0.978113340.817563870.971999280.797743040.88494998Initial


Next, you want to rotate the factor pattern such that most variables would have zero loadings on most factors. In this example, you specified a promax rotation with a varimax prerotation. To yield the prerotated factor pattern, the initial factor loading matrix is post-multiplied by an orthogonal transformation matrix that satisfies the varimax criterion. This orthogonal transformation matrix, as well as the varimax-rotated factor pattern, is shown in Output 10.3.50. The rotation leads to small loadings of Population and Employment on the first factor and small loadings of HouseValue and School on the second factor. Services appears to have a larger loading on the first factor than it has on the second factor, although both loadings are substantial. Hence, Services appears to be factorially complex.

The reorder parameter helps you see the variable clusters clearly in the factor pattern. The first factor is associated more with the first three variables: HouseValue, School, and Services. The second factor is associated more with the last two variables: Population and Employment. For orthogonal factor solutions such as the current varimax-rotated solution, you can also interpret the values in the factor loading matrix as correlations. For example, HouseValue and Factor 1 have a high correlation of 0.94, whereas Population and Factor 1 have a low correlation of 0.02.

Output 10.3.50: Orthogonal Transformation and Factor Pattern (Prerotated Solution)

RowLabel12
10.788950.61446
2-0.614460.78895

VariableFactor1Factor2
HouseValue0.94072-0.00004
School0.904190.00055
Services0.790850.41509
Population0.022550.98874
Employment0.146250.97499


The variance explained by the prerotated factors, as well as the final communality estimates, is shown in Output 10.3.51. The variance explained by the factors is more evenly distributed in the varimax-rotated solution, as compared to that of the unrotated solution. Indeed, this is a typical fact for any kind of factor rotation. In the current example, before the varimax rotation, the two factors explain 2.73 and 1.72, respectively, of the common variance (see Output 10.3.48). After the varimax rotation, the two rotated factors explain 2.35 and 2.10, respectively, of the common variance. However, the total variance explained by the factors remains unchanged after the varimax rotation. This invariance property is also observed for the communalities of the variables after the rotation, as you can see by comparing the current communality estimates in Output 10.3.48 to those in Output 10.3.49.

Output 10.3.51: Variance Explained and Final Communalities (Prerotated Solution)

Factor1Factor2Solution
2.34985672.1005128Prerotated

PopulationSchoolEmploymentServicesHouseValueSolution
0.978113340.817563870.971999280.797743040.88494998Prerotated


Some factor analysts believe that common factors are seldom orthogonal. Thus an obliquely rotated factor solution might be more desirable, or at least it should be attempted. In the current example, you used the rotate parameter to request a promax rotation, which allows factors to be correlated. Output 10.3.52 shows the Procrustes target, followed by the display of the Procrustes transformation matrix. This is the matrix that transforms the varimax factor pattern so that the rotated pattern is as close as possible to the Procrustes target, which is created by exponentiating the elements of the prerotated factor pattern (while keeping the signs of the values). However, because the variances of factors must be fixed at 1 during the oblique transformation, a normalized version of the Procrustes transformation matrix is the one that is actually used in the transformation. This normalized transformation matrix is shown at the bottom of Output 10.3.52.

Output 10.3.52: Promax Rotation: Procrustes Target and Transformation Matrices

VariableFactor1Factor2
HouseValue1.00000-0.00000
School1.000000.00000
Services0.694210.10045
Population0.000011.00000
Employment0.003260.96793

RowLabel12
11.04117-0.09865
2-0.105720.96303

RowLabel12
10.738030.54202
2-0.705550.86528


Using this transformation matrix leads to the promax-rotated factor solution, as shown in Output 10.3.53. After the promax rotation, the factors are no longer uncorrelated. As shown in the "Interfactor Correlations" table, the correlation of the two factors is now 0.20. In the unrotated and the varimax solutions, the two factors are not correlated.

Output 10.3.53: Promax Rotation: Factor Correlations and Rotated Factor Pattern

RowNameFactor1Factor2
Factor11.000000.20188
Factor20.201881.00000

VariableFactor1Factor2
HouseValue0.95558-0.09792
School0.91842-0.09352
Services0.760530.33932
Population-0.079081.00192
Employment0.047990.97509


Unlike orthogonal factor solutions, where you can interpret the factor loadings as correlations between variables and factors, in oblique factor solutions such as the promax solution, you have to turn to the factor structure matrix to examine the correlations between variables and factors. Output 10.3.54 shows the factor structures for the promax-rotated solution. In this example, the factor structure matrix reflects a pattern similar to that of the factor pattern matrix shown in Output 10.3.53. The critical difference is that you can have the correlation interpretation only by using the factor structure matrix. For example, in the factor structure matrix, the correlation between Population and Factor 2 is 0.986. The corresponding value shown in the factor pattern matrix is 1.002, which you certainly cannot interpret as a correlation coefficient.

Output 10.3.54: Factor Structure

VariableFactor1Factor2
HouseValue0.935820.09500
School0.899540.09189
Services0.829030.49286
Population0.123190.98596
Employment0.244840.98478


When factors are correlated, the common variance explained by each factor is not as straightforward as it is in the case when the factors are uncorrelated. The contributions from the other factors must be either eliminated or ignored. Both computations are shown in Output 10.3.55.

When you ignore the other factor, the common variance explained by the promax-rotated factors is 2.45 and 2.20, respectively. In contrast with orthogonal factor solutions (such as the prerotated varimax solution), the variance explained by these promax-rotated factors (ignoring other factors) does not sum to the total communality estimate of 4.45 (see Output 10.3.56).

Also shown in Output 10.3.55 is the "Variance Explained by Each Factor, Eliminating Other Factors" table. The values in this table represent unique variances explained by the factors, partialing out the variances explained by all other factors (or eliminating all other factors, as the table title suggests). In the current example, Factor 1 explains 2.25 of the variable variances, partialing out all variable variances explained by Factor 2.

Output 10.3.55: Variance Explained

Factor1Factor2Solution
2.44734952.2022803Rotated

Factor1Factor2Solution
2.44734952.2022803Rotated


The communalities of the variables, as shown in Output 10.3.56, do not change from rotation to rotation. They are still the same set of communalities in the initial, varimax-rotated, and promax-rotated solutions. This is a basic fact about factor rotations: they redistribute the variance explained by the factors; the total variance explained by the factors for any variable (that is, the communality of the variable) remains unchanged.

Output 10.3.56: Final Communalities

PopulationSchoolEmploymentServicesHouseValueSolution
0.978113340.817563870.971999280.797743040.88494998Rotated


Last updated: May 21, 2026