Written and maintained by CASRAI Editorial Board
Last updated
summarize, tabstat, and codebook all report descriptive statistics on a Stata dataset, and researchers new to Stata often reach for whichever one they saw first rather than the one built for the job at hand. They are not interchangeable: summarize is the fast default overview, tabstat is the flexible, groupable table builder, and codebook is a data-screening and documentation tool that happens to report descriptive statistics as a side effect of describing what a variable actually contains. Knowing which one answers a given question saves a step in almost every analysis session.
summarize: the default quick look
The basic syntax is summarize varlist (abbreviated su), e.g. summarize age income satisfaction. Run with no varlist at all, it summarizes every numeric variable currently in memory. The default output is a fixed five-column table — Obs, Mean, Std. Dev., Min, Max — one row per variable, computed from the observations with non-missing values on that variable (each variable’s row can therefore have a different Obs count if missingness differs across variables).
The detail option expands this into percentiles (1st, 5th, 10th, 25th, 50th, 75th, 90th, 95th, 99th), the four smallest and four largest values, variance, skewness, and kurtosis — useful for a quick distributional check before deciding whether a variable needs a transformation or a nonparametric test. summarize takes no by() option of its own; grouped summaries go through the general Stata prefix, by groupvar, sort: summarize varlist (or the shorthand bysort groupvar: summarize varlist), which repeats the whole summarize table once per group value, printed one after another.
That repetition is exactly where summarize stops being the right tool: for more than two or three groups, or for more than one or two variables, the stacked output becomes long and hard to scan side by side. That is the gap tabstat fills.
tabstat: a compact, choosable table
The syntax is tabstat varlist [if] [in] [weight], statistics(statlist) by(groupvar) columns(variables|statistics). Unlike summarize, which always reports the same five statistics, tabstat‘s statistics() option (default mean alone) accepts any combination — statistics(n mean sd min max), or percentiles like statistics(p25 p50 p75) for a quartile table without switching to summarize, detail and reading percentiles off a longer report.
by(groupvar) is the direct answer to the grouping gap above: instead of one repeated block per group, tabstat income, statistics(mean sd n) by(region) produces one compact table with a row per region and an overall row at the bottom — the layout a results table in a paper or report actually needs, without manual reassembly.
columns() controls orientation: columns(variables) (the default when summarizing more than one variable) puts variables across the top and statistics down the side; columns(statistics) flips it, useful when a variable list is long and a statistic list is short. format applies each variable’s own display format instead of tabstat’s default %9.0g, which matters when a variable is stored with a specific number of decimal places that %9.0g would otherwise round away. tabstat also supports save, which stores the resulting numbers in Stata’s returned results (r()) instead of only printing them — the mechanism most export routines (or a short post-command script writing to a table) read from rather than re-parsing printed output.
codebook: screening the data, not just describing it
The syntax is codebook [varlist], and with no varlist it runs on every variable in memory. Its job is different in kind from the two commands above: rather than a single, uniform statistics table, codebook inspects each variable’s type, label, range, and number of unique values, and prints a report tailored to what the variable looks like — a numeric variable under the categorical threshold (tabulate(), default 9 unique values) gets a value-by-value tabulation with its labels; a continuous numeric variable gets range, mean, and standard deviation; a string variable gets its length and a note if it looks unlabeled or unformatted.
Several options turn codebook specifically into a first-pass data-screening step, which is where it earns a place in a workflow that summarize and tabstat do not cover:
problemsflags issues rather than describing normal data — undefined value labels, variables that are constant across every observation, and string variables containing leading/trailing spaces or unusual characters that would silently break a merge or a string comparison later.mvexamines the pattern of missing values across the variable list, at a real CPU cost on a large dataset, so it is worth running deliberately rather than by default on every codebook call.compactcollapses the report to one line per variable — a fast scan across a wide dataset when the full per-variable report would be too long to read.headeradds the dataset name and last-saved date to the top of the output, useful when documenting exactly which version of a dataset a codebook run describes.
None of that is what summarize or tabstat are for. Running codebook right after importing a new dataset, before any analysis command, catches problems — a variable that should be categorical but imported as continuous, a string variable with stray whitespace, an accidentally constant column — that a summarize table would not surface, because summarize assumes the data is already clean enough to describe.
Choosing between the three
In practice the three map onto three different questions, and a single analysis session usually uses all of them at different points:
- “What does this dataset actually contain, and is anything wrong with it?” —
codebook, run once right after import, ideally withproblems. - “What are the basic numbers for this variable list, quickly?” —
summarize, for a fast look at one variable list, orsummarize, detailwhen the distribution shape itself matters. - “I need a specific, groupable, or customized statistics table” —
tabstat, whenever the output needs to go into a manuscript table, needs a non-default set of statistics, or needs to be broken out by group without the repeated-block output ofby: summarize.
A worked example
A dataset has age, income, and satisfaction collected across three study sites (site). A reasonable sequence:
. codebook age income satisfaction site, problems . summarize age income satisfaction, detail . tabstat age income satisfaction, statistics(n mean sd) by(site) columns(statistics)
codebook ..., problems first confirms site is genuinely categorical with defined labels and flags anything unexpected — a stray fourth site code, an undefined label, a constant variable that made it into the list by mistake. summarize, detail next gives a fast distributional check across all three continuous variables in one table, including whether income looks skewed enough to warrant a log transform or a nonparametric approach. tabstat ..., by(site) then produces the actual by-site comparison table — n, mean, and standard deviation for each variable at each site, in one compact block, which is the shape a results table in a write-up needs rather than three separate summarize blocks pasted one after another.
Related CASRAI guides
For the underlying statistical concepts these commands report — what a mean, standard deviation, or measure of dispersion actually represents and how to write it up — see Descriptive Statistics: Central Tendency, Dispersion, Shape, and How to Report Them. For the same task in SPSS instead of Stata, see Descriptive Statistics in SPSS, and for choosing between the two packages generally, SPSS vs. Stata for Statistical Analysis. codebook‘s data-screening role sits alongside the broader research-data-management concept of a codebook as a documentation artifact — see Codebook: What It Is, What Goes in One, and How to Build One. For the next step once variables look clean, Correlation Matrices in Stata covers correlate and pwcorr, and How to Choose a Statistical Test covers what to run once the descriptive picture is in hand. For keeping this whole sequence reproducible, see Stata Do-Files: Structure for a Reproducible Workflow.








