/* PSPP - a program for statistical analysis.
- Copyright (C) 2009 Free Software Foundation, Inc.
+ Copyright (C) 2009, 2010 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
#include <libpspp/misc.h>
#include <libpspp/message.h>
-#include <output/table.h>
+#include <output/tab.h>
+#include <output/charts/scree.h>
+#include <output/chart-item.h>
#include "gettext.h"
#define _(msgid) gettext (msgid)
EXTRACTION_PAF,
};
+enum plot_opts
+ {
+ PLOT_SCREE = 0x0001,
+ PLOT_ROTATION = 0x0002
+ };
+
enum print_opts
{
PRINT_UNIVARIATE = 0x0001,
enum mv_class exclude;
enum print_opts print;
enum extraction_method extraction;
+ enum plot_opts plot;
/* Extraction Criteria */
int n_factors;
factor.econverge = 0.001;
factor.blank = 0;
factor.sort = false;
+ factor.plot = 0;
factor.wv = dict_get_weight (dict);
PV_NO_DUPLICATE | PV_NUMERIC))
goto error;
+ if (factor.n_vars < 2)
+ msg (MW, _("Factor analysis on a single variable is not useful."));
+
while (lex_token (lexer) != '.')
{
lex_match (lexer, '/');
-#if FACTOR_FULLY_IMPLEMENTED
if (lex_match_id (lexer, "PLOT"))
{
lex_match (lexer, '=');
{
if (lex_match_id (lexer, "EIGEN"))
{
+ factor.plot |= PLOT_SCREE;
}
+#if FACTOR_FULLY_IMPLEMENTED
else if (lex_match_id (lexer, "ROTATION"))
{
}
+#endif
else
{
lex_error (lexer, NULL);
}
}
}
- else
-#endif
- if (lex_match_id (lexer, "METHOD"))
+ else if (lex_match_id (lexer, "METHOD"))
{
lex_match (lexer, '=');
while (lex_token (lexer) != '.' && lex_token (lexer) != '/')
}
+static void
+show_scree (const struct cmd_factor *f, struct idata *idata)
+{
+ struct scree *s;
+ const char *label ;
+
+ if ( !(f->plot & PLOT_SCREE) )
+ return;
+
+
+ label = f->extraction == EXTRACTION_PC ? _("Component Number") : _("Factor Number");
+
+ s = scree_create (idata->eval, label);
+
+ scree_submit (s);
+}
static void
show_communalities (const struct cmd_factor * factor,
tab_title (t, _("Communalities"));
- tab_dim (t, tab_natural_dimensions, NULL, NULL);
-
tab_headers (t, heading_columns, 0, heading_rows, 0);
c = 1;
show_factor_matrix (const struct cmd_factor *factor, struct idata *idata, const gsl_matrix *fm)
{
int i;
- const int n_factors = n_extracted_factors (factor, idata);
+ const int n_factors = idata->n_extractions;
const int heading_columns = 1;
const int heading_rows = 2;
else
tab_title (t, _("Factor Matrix"));
- tab_dim (t, tab_natural_dimensions, NULL, NULL);
-
tab_headers (t, heading_columns, 0, heading_rows, 0);
if ( factor->extraction == EXTRACTION_PC )
tab_title (t, _("Total Variance Explained"));
- tab_dim (t, tab_natural_dimensions, NULL, NULL);
-
tab_headers (t, heading_columns, 0, heading_rows, 0);
/* Outline the box */
for (i = 0; i < (nc - heading_columns) / 3 ; ++i)
{
tab_text (t, i * 3 + 1, 1, TAB_CENTER | TAT_TITLE, _("Total"));
+ /* xgettext:no-c-format */
tab_text (t, i * 3 + 2, 1, TAB_CENTER | TAT_TITLE, _("% of Variance"));
tab_text (t, i * 3 + 3, 1, TAB_CENTER | TAT_TITLE, _("Cumulative %"));
if (factor->print & PRINT_EXTRACTION)
{
- if ( i < n_extracted_factors (factor, idata))
+ if (i < idata->n_extractions)
{
/* Sums of squared loadings */
tab_double (t, c++, i + heading_rows, 0, e_lambda, NULL);
tab_title (t, _("Correlation Matrix"));
- tab_dim (t, tab_natural_dimensions, NULL, NULL);
-
tab_hline (t, TAL_1, 0, nc - 1, heading_rows);
if (nr > heading_rows)
struct tab_table *t = tab_create (nc, nr);
tab_title (t, _("Descriptive Statistics"));
- tab_dim (t, tab_natural_dimensions, NULL, NULL);
tab_headers (t, heading_columns, 0, heading_rows, 0);
gsl_eigen_symmv_sort (idata->eval, idata->evec, GSL_EIGEN_SORT_ABS_DESC);
#endif
+ idata->n_extractions = n_extracted_factors (factor, idata);
+
+ if (idata->n_extractions == 0)
+ {
+ msg (MW, _("The FACTOR criteria result in zero factors extracted. Therefore no analysis will be performed."));
+ goto finish;
+ }
+
+ if (idata->n_extractions > factor->n_vars)
+ {
+ msg (MW, _("The FACTOR criteria result in more factors than variables, which is not meaningful. No analysis will be performed."));
+ goto finish;
+ }
+
{
const gsl_vector *extracted_eigenvalues = NULL;
gsl_vector *initial_communalities = gsl_vector_alloc (factor->n_vars);
gsl_vector *extracted_communalities = gsl_vector_alloc (factor->n_vars);
size_t i;
- struct factor_matrix_workspace *fmw = factor_matrix_workspace_alloc (idata->msr->size, n_extracted_factors (factor, idata));
+ struct factor_matrix_workspace *fmw = factor_matrix_workspace_alloc (idata->msr->size, idata->n_extractions);
gsl_matrix *factor_matrix = gsl_matrix_calloc (factor->n_vars, fmw->n_factors);
if ( factor->extraction == EXTRACTION_PAF)
}
else if (factor->extraction == EXTRACTION_PC)
{
- for (i = 0 ; i < factor->n_vars; ++i)
- {
- gsl_vector_set (initial_communalities, i, communality (idata, i, factor->n_vars));
- }
+ for (i = 0; i < factor->n_vars; ++i)
+ gsl_vector_set (initial_communalities, i, communality (idata, i, factor->n_vars));
+
gsl_vector_memcpy (extracted_communalities, initial_communalities);
iterate_factor_matrix (analysis_matrix, extracted_communalities, factor_matrix, fmw);
factor_matrix_workspace_free (fmw);
+ show_scree (factor, idata);
+
show_factor_matrix (factor, idata, factor_matrix);
gsl_vector_free (initial_communalities);
gsl_vector_free (extracted_communalities);
}
+ finish:
+
idata_free (idata);
casereader_destroy (r);