+@itemize @w{}
+@item
+@subcmd{TABLES}, the default, causes crosstabulation tables to be output.
+@subcmd{NOTABLES}, which is equivalent to @code{CELLS=NONE}, suppresses them.
+
+@item
+@subcmd{AVALUE}, the default, causes values to be sorted in ascending order.
+@subcmd{DVALUE} asserts a descending sort order.
+@end itemize
+
+The @subcmd{CELLS} subcommand controls the contents of each cell in the displayed
+crosstabulation table. The possible settings are:
+
+@table @asis
+@item COUNT
+Frequency count.
+@item ROW
+Row percent.
+@item COLUMN
+Column percent.
+@item TOTAL
+Table percent.
+@item EXPECTED
+Expected value.
+@item RESIDUAL
+Residual.
+@item SRESIDUAL
+Standardized residual.
+@item ASRESIDUAL
+Adjusted standardized residual.
+@item ALL
+All of the above.
+@item NONE
+Suppress cells entirely.
+@end table
+
+@samp{/CELLS} without any settings specified requests @subcmd{COUNT}, @subcmd{ROW},
+@subcmd{COLUMN}, and @subcmd{TOTAL}.
+If @subcmd{CELLS} is not specified at all then only @subcmd{COUNT}
+is selected.
+
+By default, crosstabulation and statistics use raw case weights,
+without rounding. Use the @subcmd{/COUNT} subcommand to perform
+rounding: CASE rounds the weights of individual weights as cases are
+read, CELL rounds the weights of cells within each crosstabulation
+table after it has been constructed, and ASIS explicitly specifies the
+default non-rounding behavior. When rounding is requested, ROUND, the
+default, rounds to the nearest integer and TRUNCATE rounds toward
+zero.
+
+The @subcmd{STATISTICS} subcommand selects statistics for computation:
+
+@table @asis
+@item CHISQ
+@cindex chi-square
+
+Pearson chi-square, likelihood ratio, Fisher's exact test, continuity
+correction, linear-by-linear association.
+@item PHI
+Phi.
+@item CC
+Contingency coefficient.
+@item LAMBDA
+Lambda.
+@item UC
+Uncertainty coefficient.
+@item BTAU
+Tau-b.
+@item CTAU
+Tau-c.
+@item RISK
+Risk estimate.
+@item GAMMA
+Gamma.
+@item D
+Somers' D.
+@item KAPPA
+Cohen's Kappa.
+@item ETA
+Eta.
+@item CORR
+Spearman correlation, Pearson's r.
+@item ALL
+All of the above.
+@item NONE
+No statistics.
+@end table
+
+Selected statistics are only calculated when appropriate for the
+statistic. Certain statistics require tables of a particular size, and
+some statistics are calculated only in integer mode.
+
+@samp{/STATISTICS} without any settings selects CHISQ. If the
+@subcmd{STATISTICS} subcommand is not given, no statistics are calculated.
+
+@cindex bar chart
+The @samp{/BARCHART} subcommand produces a clustered bar chart for the first two
+variables on each table.
+If a table has more than two variables, the counts for the third and subsequent levels
+are aggregated and the chart is produced as if there were only two variables.
+
+
+@strong{Please note:} Currently the implementation of @cmd{CROSSTABS} has the
+following limitations:
+
+@itemize @bullet
+@item
+Significance of some symmetric and directional measures is not calculated.
+@item
+Asymptotic standard error is not calculated for
+Goodman and Kruskal's tau or symmetric Somers' d.
+@item
+Approximate T is not calculated for symmetric uncertainty coefficient.
+@end itemize
+
+Fixes for any of these deficiencies would be welcomed.
+
+@subsection Crosstabs Example
+
+@cindex chi-square test of independence
+
+A researcher wishes to know if, in an industry, a person's sex is related to
+the person's occupation. To investigate this, she has determined that the
+@file{personnel.sav} is a representative, randomly selected sample of persons.
+The researcher's null hypothesis is that a person's sex has no relation to a
+person's occupation. She uses a chi-squared test of independence to investigate
+the hypothesis.
+
+@float Example, crosstabs:ex
+@psppsyntax {crosstabs.sps}
+@caption {Running crosstabs on the @exvar{sex} and @exvar{occupation} variables}
+@end float
+
+The syntax in @ref{crosstabs:ex} conducts a chi-squared test of independence.
+The line @code{/tables = occupation by sex} indicates that @exvar{occupation}
+and @exvar{sex} are the variables to be tabulated. To do this using the @gui{}
+you must place these variable names respectively in the @samp{Row} and
+@samp{Column} fields as shown in @ref{crosstabs:scr}.
+
+@float Screenshot, crosstabs:scr
+@psppimage {crosstabs}
+@caption {The Crosstabs dialog box with the @exvar{sex} and @exvar{occupation} variables selected}
+@end float
+
+Similarly, the @samp{Cells} button shows a dialog box to select the @code{count}
+and @code{expected} options. All other cell options can be deselected for this
+test.
+
+You would use the @samp{Format} and @samp{Statistics} buttons to select options
+for the @subcmd{FORMAT} and @subcmd{STATISTICS} subcommands. In this example,
+the @samp{Statistics} requires only the @samp{Chisq} option to be checked. All
+other options should be unchecked. No special settings are required from the
+@samp{Format} dialog.
+
+As shown in @ref{crosstabs:res} @cmd{CROSSTABS} generates a contingency table
+containing the observed count and the expected count of each sex and each
+occupation. The expected count is the count which would be observed if the
+null hypothesis were true.
+
+The significance of the Pearson Chi-Square value is very much larger than the
+normally accepted value of 0.05 and so one cannot reject the null hypothesis.
+Thus the researcher must conclude that a person's sex has no relation to the
+person's occupation.
+
+@float Results, crosstabs:res
+@psppoutput {crosstabs}
+@caption {The results of a test of independence between @exvar{sex} and @exvar{occupation}}
+@end float
+
+@node CTABLES
+@section CTABLES
+
+@vindex CTABLES
+@cindex custom tables
+@cindex tables, custom
+
+@code{CTABLES} has the following overall syntax. At least one
+@code{TABLE} subcommand is required:
+
+@display
+@t{CTABLES}
+ @dots{}@i{global subcommands}@dots{}
+ [@t{/TABLE} @i{axis} [@t{BY} @i{axis} [@t{BY} @i{axis}]]
+ @dots{}@i{per-table subcommands}@dots{}]@dots{}
+@end display
+
+@noindent
+where each @i{axis} may be empty or take one of the following forms:
+
+@display
+@i{variable}
+@i{variable} @t{[}@{@t{C} @math{|} @t{S}@}@t{]}
+@i{axis} + @i{axis}
+@i{axis} > @i{axis}
+(@i{axis})
+@i{axis} @t{[}@i{summary} [@i{string}] [@i{format}]@t{]}
+@end display
+
+The following subcommands precede the first @code{TABLE} subcommand
+and apply to all of the output tables. All of these subcommands are
+optional:
+
+@display
+@t{/FORMAT}
+ [@t{MINCOLWIDTH=}@{@t{DEFAULT} @math{|} @i{width}@}]
+ [@t{MAXCOLWIDTH=}@{@t{DEFAULT} @math{|} @i{width}@}]
+ [@t{UNITS=}@{@t{POINTS} @math{|} @t{INCHES} @math{|} @t{CM}@}]
+ [@t{EMPTY=}@{@t{ZERO} @math{|} @t{BLANK} @math{|} @i{string}@}]
+ [@t{MISSING=}@i{string}]
+@t{/VLABELS}
+ @t{VARIABLES=}@i{variables}
+ @t{DISPLAY}=@{@t{DEFAULT} @math{|} @t{NAME} @math{|} @t{LABEL} @math{|} @t{BOTH} @math{|} @t{NONE}@}
+@ignore @c not yet implemented
+@t{/MRSETS COUNTDUPLICATES=}@{@t{YES} @math{|} @t{NO}@}
+@end ignore
+@t{/SMISSING} @{@t{VARIABLE} @math{|} @t{LISTWISE}@}
+@t{/PCOMPUTE} @t{&}@i{postcompute}@t{=EXPR(}@i{expression}@t{)}
+@t{/PPROPERTIES} @t{&}@i{postcompute}@dots{}
+ [@t{LABEL=}@i{string}]
+ [@t{FORMAT=}[@i{summary} @i{format}]@dots{}]
+ [@t{HIDESOURCECATS=}@{@t{NO} @math{|} @t{YES}@}
+@t{/WEIGHT VARIABLE=}@i{variable}
+@t{/HIDESMALLCOUNTS COUNT=@i{count}}
+@end display
+
+The following subcommands follow @code{TABLE} and apply only to the
+previous @code{TABLE}. All of these subcommands are optional:
+
+@display
+@t{/SLABELS}
+ [@t{POSITION=}@{@t{COLUMN} @math{|} @t{ROW} @math{|} @t{LAYER}@}]
+ [@t{VISIBLE=}@{@t{YES} @math{|} @t{NO}@}]
+@t{/CLABELS} @{@t{AUTO} @math{|} @{@t{ROWLABELS}@math{|}@t{COLLABELS}@}@t{=}@{@t{OPPOSITE}@math{|}@t{LAYER}@}@}
+@t{/CATEGORIES} @t{VARIABLES=}@i{variables}
+ @{@t{[}@i{value}@t{,} @i{value}@dots{}@t{]}
+ @math{|} [@t{ORDER=}@{@t{A} @math{|} @t{D}@}]
+ [@t{KEY=}@{@t{VALUE} @math{|} @t{LABEL} @math{|} @i{summary}@t{(}@i{variable}@t{)}@}]
+ [@t{MISSING=}@{@t{EXCLUDE} @math{|} @t{INCLUDE}@}]@}
+ [@t{TOTAL=}@{@t{NO} @math{|} @t{YES}@} [@t{LABEL=}@i{string}] [@t{POSITION=}@{@t{AFTER} @math{|} @t{BEFORE}@}]]
+ [@t{EMPTY=}@{@t{INCLUDE} @math{|} @t{EXCLUDE}@}]
+@t{/TITLES}
+ [@t{TITLE=}@i{string}@dots{}]
+ [@t{CAPTION=}@i{string}@dots{}]
+ [@t{CORNER=}@i{string}@dots{}]
+@ignore @c not yet implemented
+@t{/CRITERIA CILEVEL=}@i{percentage}
+@t{/SIGTEST TYPE=CHISQUARE}
+ [@t{ALPHA=}@i{siglevel}]
+ [@t{INCLUDEMRSETS=}@{@t{YES} @math{|} @t{NO}@}]
+ [@t{CATEGORIES=}@{@t{ALLVISIBLE} @math{|} @t{SUBTOTALS}@}]
+@t{/COMPARETEST TYPE=}@{@t{PROP} @math{|} @t{MEAN}@}
+ [@t{ALPHA=}@i{value}[@t{,} @i{value}]]
+ [@t{ADJUST=}@{@t{BONFERRONI} @math{|} @t{BH} @math{|} @t{NONE}@}]
+ [@t{INCLUDEMRSETS=}@{@t{YES} @math{|} @t{NO}@}]
+ [@t{MEANSVARIANCE=}@{@t{ALLCATS} @math{|} @t{TESTEDCATS}@}]
+ [@t{CATEGORIES=}@{@t{ALLVISIBLE} @math{|} @t{SUBTOTALS}@}]
+ [@t{MERGE=}@{@t{NO} @math{|} @t{YES}@}]
+ [@t{STYLE=}@{@t{APA} @math{|} @t{SIMPLE}@}]
+ [@t{SHOWSIG=}@{@t{NO} @math{|} @t{YES}@}]
+@end ignore
+@end display
+
+The @code{CTABLES} (aka ``custom tables'') command produces
+multi-dimensional tables from categorical and scale data. It offers
+many options for data summarization and formatting.
+
+This section's examples use data from the 2008 (USA) National Survey
+of Drinking and Driving Attitudes and Behaviors, a public domain data
+set from the (USA) National Highway Traffic Administration and
+available at @url{https://data.transportation.gov}. @pspp{} includes
+this data set, with a slightly modified dictionary, as
+@file{examples/nhtsa.sav}.
+
+@node CTABLES Basics
+@subsection Basics
+
+The only required subcommand is @code{TABLE}, which specifies the
+variables to include along each axis:
+@display
+@t{/TABLE} @i{rows} [@t{BY} @i{columns} [@t{BY} @i{layers}]]
+@end display
+@noindent
+In @code{TABLE}, each of @var{rows}, @var{columns}, and @var{layers}
+is either empty or an axis expression that specifies one or more
+variables. At least one must specify an axis expression.
+
+@menu
+* CTABLES Categorical Variable Basics::
+* CTABLES Scalar Variable Basics::
+* CTABLES Overriding Measurement Level::
+@end menu
+
+@node CTABLES Categorical Variable Basics
+@subsubsection Categorical Variables
+
+An axis expression that names a categorical variable divides the data
+into cells according to the values of that variable. When all the
+variables named on @code{TABLE} are categorical, by default each cell
+displays the number of cases that it contains, so specifying a single
+variable yields a frequency table:
+
+@example
+CTABLES /TABLE=AgeGroup.
+@end example
+@psppoutput {ctables1}
+
+@noindent
+Specifying a row and a column categorical variable yields a
+crosstabulation:
+
+@example
+CTABLES /TABLE=AgeGroup BY qns3a.
+@end example
+@psppoutput {ctables2}
+
+@noindent
+The @samp{>} ``nesting'' operator nests multiple variables on a single
+axis, e.g.:
+
+@example
+CTABLES /TABLE qn105ba BY AgeGroup > qns3a.
+@end example
+@psppoutput {ctables3}
+
+@noindent
+The @samp{+} ``stacking'' operator allows a single output table to
+include multiple data analyses. With @samp{+}, @code{CTABLES} divides
+the output table into multiple @dfn{sections}, each of which includes
+an analysis of the full data set. For example, the following command
+separately tabulates age group and driving frequency by gender:
+
+@example
+CTABLES /TABLE AgeGroup + qn1 BY qns3a.
+@end example
+@psppoutput {ctables4}
+
+@noindent
+When @samp{+} and @samp{>} are used together, @samp{>} binds more
+tightly. Use parentheses to override operator precedence. Thus:
+
+@example
+CTABLES /TABLE qn26 + qn27 > qns3a.
+CTABLES /TABLE (qn26 + qn27) > qns3a.
+@end example
+@psppoutput {ctables5}
+
+@node CTABLES Scalar Variable Basics
+@subsubsection Scalar Variables
+
+For a categorical variable, @code{CTABLES} divides the table into a
+cell per category. For a scalar variable, @code{CTABLES} instead
+calculates a summary measure, by default the mean, of the values that
+fall into a cell. For example, if the only variable specified is a
+scalar variable, then the output is a single cell that holds the mean
+of all of the data:
+
+@example
+CTABLES /TABLE qnd1.
+@end example
+@psppoutput {ctables6}
+
+A scalar variable may nest with categorical variables. The following
+example shows the mean age of survey respondents across gender and
+language groups:
+
+@example
+CTABLES /TABLE qns3a > qnd1 BY region.
+@end example
+@psppoutput {ctables7}
+
+The order of nesting of scalar and categorical variables affects table
+labeling, but it does not affect the data displayed in the table. The
+following example shows how the output changes when the nesting order
+of the scalar and categorical variable are interchanged:
+
+@example
+CTABLES /TABLE qnd1 > qns3a BY region.
+@end example
+@psppoutput {ctables8}
+
+Only a single scalar variable may appear in each section; that is, a
+scalar variable may not nest inside a scalar variable directly or
+indirectly. Scalar variables may only appear on one axis within
+@code{TABLE}.
+
+@node CTABLES Overriding Measurement Level
+@subsubsection Overriding Measurement Level
+
+By default, @code{CTABLES} uses a variable's measurement level to
+decide whether to treat it as categorical or scalar. Variables
+assigned the nominal or ordinal measurement level are treated as
+categorical, and scalar variables are treated as scalar.
+
+Use the @code{VARIABLE LEVEL} command to change a variable's
+measurement level (@pxref{VARIABLE LEVEL}). To treat a variable as
+categorical or scalar only for one use on @code{CTABLES}, add
+@samp{[C]} or @samp{[S]}, respectively, after the variable name. The
+following example shows how to analyze the scalar variable @code{qn20}
+as categorical:
+
+@example
+CTABLES /TABLE qn20 [C] BY qns3a.
+@end example
+@psppoutput {ctables9}
+
+@ignore
+@node CTABLES Multiple Response Sets
+@subsubheading Multiple Response Sets
+
+The @code{CTABLES} command does not yet support multiple response
+sets.
+@end ignore
+
+@node CTABLES Data Summarization
+@subsection Data Summarization
+
+The @code{CTABLES} command allows the user to control how the data are
+summarized with summary specifications, which are enclosed in square
+brackets following a variable name on the @code{TABLE} subcommand.
+When all the variables are categorical, summary specifications can be
+given for the innermost nested variables on any one axis. When a
+scalar variable is present, only the scalar variable may have summary
+specifications. The following example includes a summary
+specification for column and row percentages for categorical
+variables, and mean and median for a scalar variable:
+
+@example
+CTABLES
+ /TABLE=qnd1 [MEAN, MEDIAN] BY qns3a
+ /TABLE=AgeGroup [COLPCT, ROWPCT] BY qns3a.
+@end example
+@psppoutput {ctables10}
+
+A summary specification may override the default label and format by
+appending a string or format specification or both (in that order) to
+the summary function name. For example:
+
+@example
+CTABLES /TABLE=AgeGroup [COLPCT 'Gender %' PCT5.0,
+ ROWPCT 'Age Group %' PCT5.0]
+ BY qns3a.
+@end example
+@psppoutput {ctables11}
+
+Parentheses provide a shorthand to apply summary specifications to
+multiple variables. For example, both of these commands:
+
+@example
+CTABLES /TABLE=AgeGroup[COLPCT] + qns1[COLPCT] BY qns3a.
+CTABLES /TABLE=(AgeGroup + qns1)[COLPCT] BY qns3a.
+@end example
+
+@noindent
+produce the same output shown below:
+
+@psppoutput {ctables12}
+
+The following sections list the available summary functions.
+
+@menu
+* CTABLES Summary Functions for Individual Cells::
+* CTABLES Summary Functions for Groups of Cells::
+* CTABLES Summary Functions for Adjusted Weights::
+* CTABLES Unweighted Summary Functions::
+@end menu
+
+@node CTABLES Summary Functions for Individual Cells
+@subsubsection Summary Functions for Individual Cells
+
+This section lists the summary functions that consider only an
+individual cell in @code{CTABLES}. Only one such summary function,
+@code{COUNT}, may be applied to both categorical and scale variables:
+
+@table @asis
+@item @code{COUNT} (``Count'')
+The sum of weights in a cell.
+
+If @code{CATEGORIES} for one or more of the variables in a table
+include missing values (@pxref{CTABLES Per-Variable Category
+Options}), then some or all of the categories for a cell might be
+missing values. @code{COUNT} counts data included in a cell
+regardless of whether its categories are missing.
+@end table
+
+The following summary functions apply only to scale variables or
+totals and subtotals for categorical variables. Be cautious about
+interpreting the summary value in the latter case, because it is not
+necessarily meaningful; however, the mean of a Likert scale, etc.@:
+may have a straightforward interpreation.
+
+@table @asis
+@item @code{MAXIMUM} (``Maximum'')
+The largest value.
+
+@item @code{MEAN} (``Mean'')
+The mean.
+
+@item @code{MEDIAN} (``Median'')
+The median value.
+
+@item @code{MINIMUM} (``Minimum'')
+The smallest value.
+
+@item @code{MISSING} (``Missing'')
+Sum of weights of user- and system-missing values.
+
+@item @code{MODE} (``Mode'')
+The highest-frequency value. Ties are broken by taking the smallest mode.
+
+@item @code{PTILE} @i{n} (``Percentile @i{n}'')
+The @var{n}th percentile, where @math{0 @leq{} @var{n} @leq{} 100}.
+
+@item @code{RANGE} (``Range'')
+The maximum minus the minimum.
+
+@item @code{SEMEAN} (``Std Error of Mean'')
+The standard error of the mean.
+
+@item @code{STDDEV} (``Std Deviation'')
+The standard deviation.
+
+@item @code{SUM} (``Sum'')
+The sum.
+
+@item @code{TOTALN} (``Total N'')
+The sum of weights in a cell.
+
+For scale data, @code{COUNT} and @code{TOTALN} are the same.
+
+For categorical data, @code{TOTALN} counts missing values in excluded
+categories, that is, user-missing values not in an explicit category
+list on @code{CATEGORIES} (@pxref{CTABLES Per-Variable Category
+Options}), or user-missing values excluded because
+@code{MISSING=EXCLUDE} is in effect on @code{CATEGORIES}, or
+system-missing values. @code{COUNT} does not count these.
+
+@item @code{VALIDN} (``Valid N'')
+The sum of valid count weights in included categories.
+
+@code{VALIDN} does not count missing values regardless of whether they
+are in included categories via @code{CATEGORIES}. @code{VALIDN} does
+not count valid values that are in excluded categories.
+
+@item @code{VARIANCE} (``Variance'')
+The variance.
+@end table
+
+@node CTABLES Summary Functions for Groups of Cells
+@subsubsection Summary Functions for Groups of Cells
+
+These summary functions summarize over multiple cells within an area
+of the output chosen by the user and specified as part of the function
+name. The following basic @var{area}s are supported, in decreasing
+order of size:
+
+@table @code
+@item TABLE
+A @dfn{section}. Stacked variables divide sections of the output from
+each other. sections may span multiple layers.
+
+@item LAYER
+A section within a single layer.
+
+@item SUBTABLE
+A @dfn{subtable}, whose contents are the cells that pair an innermost
+row variable and an innermost column variable within a single layer.
+@end table
+
+The following shows how the output for the table expression @code{qn61
+> qn57 BY qnd7a > qn86 + qn64b BY qns3a}@footnote{This is not
+necessarily a meaningful table, so for clarity variable labels are
+omitted.} is divided up into @code{TABLE}, @code{LAYER}, and
+@code{SUBTABLE} areas. Each unique value for Table ID is one section,
+and similarly for Layer ID and Subtable ID. Thus, this output has two
+@code{TABLE} areas (one for @code{qnd7a} and one for @code{qn64b}),
+four @code{LAYER} areas (for those two variables, per layer), and 12
+@code{SUBTABLE} areas.
+@psppoutput {ctables22}
+
+@code{CTABLES} also supports the following @var{area}s that further
+divide a subtable or a layer within a section:
+
+@table @code
+@item LAYERROW
+@itemx LAYERCOL
+A row or column, respectively, in one layer of a section.
+
+@item ROW
+@itemx COL
+A row or column, respectively, in a subtable.
+@end table
+
+The following summary functions for groups of cells are available for
+each @var{area} described above, for both categorical and scale
+variables:
+
+@table @asis
+@item @code{@i{area}PCT} or @code{@i{area}PCT.COUNT} (``@i{Area} %'')
+A percentage of total counts within @var{area}.
+
+@item @code{@i{area}PCT.VALIDN} (``@i{Area} Valid N %'')
+A percentage of total counts for valid values within @var{area}.
+
+@item @code{@i{area}PCT.TOTALN} (``@i{Area} Total N %'')
+A percentage of total counts for all values within @var{area}.
+@end table
+
+Scale variables and totals and subtotals for categorical variables may
+use the following additional group cell summary function:
+
+@table @asis
+@item @code{@i{area}PCT.SUM} (``@i{Area} Sum %'')
+Percentage of the sum of the values within @var{area}.
+@end table
+
+@node CTABLES Summary Functions for Adjusted Weights
+@subsubsection Summary Functions for Adjusted Weights
+
+If the @code{WEIGHT} subcommand specified an adjustment weight
+variable, then the following summary functions use its value instead
+of the dictionary weight variable. Otherwise, they are equivalent to
+the summary function without the @samp{E}-prefix:
+
+@itemize @bullet
+@item
+@code{ECOUNT} (``Adjusted Count'')
+
+@item
+@code{ETOTALN} (``Adjusted Total N'')
+
+@item
+@code{EVALIDN} (``Adjusted Valid N'')
+@end itemize
+
+@node CTABLES Unweighted Summary Functions
+@subsubsection Unweighted Summary Functions
+
+The following summary functions with a @samp{U}-prefix are equivalent
+to the same ones without the prefix, except that they use unweighted
+counts:
+