Written and maintained by CASRAI Editorial Board
Last updated
Stata separates two kinds of label with two different commands: label variable names a column, while label define plus label values names the numeric codes stored inside it. A variable label is a one-line description attached directly to a single variable — label variable sat "Overall satisfaction (1-5 scale)". A value label is different: it is a separate, named object — built once with label define and then attached to one or more variables with label values — that translates the raw integers Stata stores (1, 2, 3…) into readable text (Male, Female, Strongly agree…) purely for display.
The distinction matters because the two commands solve different problems. This page covers the syntax for both, why value labels are defined separately from the variables that use them, and why that split is what stops a shared do-file from reducing to “wait, what does a 3 mean here again?” once more than one person is working on the dataset.
The problem labels solve: numeric codes with no explanation
Survey and administrative data almost always arrives, or gets recoded, as small integers — a gender field stored as 1/2, a five-point agreement scale stored as 1-5, a yes/no field stored as 0/1. Stata is fast specifically because it works with these integers rather than long text strings. The tradeoff is that a raw listing of the data is unreadable to anyone who does not already have the codebook open next to it:
. list in 1/5 +--------------------+ | id gender sat | |--------------------| 1. | 1 1 4 | 2. | 2 2 5 | 3. | 3 1 3 | 4. | 4 2 4 | 5. | 5 1 2 | +--------------------+
Nothing here says whether 1 is male or female, or whether a satisfaction score of 5 is the best or worst end of the scale. In a do-file you wrote yourself last week that might not matter yet — but in a do-file handed to a co-author, a research assistant, or your own future self six months from now, it is exactly the ambiguity that produces a wrongly-signed table or a mislabeled chart. Labeling before you run any analysis is what keeps the numbers self-explanatory once the file leaves your hands.
Variable labels: label variable names the column
The syntax is:
label variable varname "text"
Variable labels are short descriptive text — up to 80 characters — attached to one specific variable. They show up in describe, codebook, the Variables window, and in the row/column headers of many output tables, which is usually more informative than the bare variable name a dataset arrived with:
. label variable gender "Respondent gender" . label variable sat "Overall satisfaction (1-5 scale)" . describe gender sat storage display value variable name type format label variable label -------------------------------------------------------------------- gender byte %8.0g Respondent gender sat byte %8.0g Overall satisfaction (1-5 scale)
A variable label describes the column — what the field represents. It does not touch the values stored inside it, and running label variable varname with no text after it clears the label. It is also a one-to-one relationship: every variable gets its own label text, written once, used once.
Value labels: label define and label values name the codes
Value labels work differently, and it takes two commands because a value label is a reusable object, not a property of any one variable:
label define lblname # "text" [# "text" ...] [, modify] label values varlist lblname
label define builds a named mapping from integers to text — a “value label” — that exists independently in the dataset, unattached to anything yet. label values is the separate step that actually attaches a defined label to one or more variables:
. label define sexlbl 1 "Male" 2 "Female" . label values gender sexlbl . label define agreelbl 1 "Strongly disagree" 2 "Disagree" 3 "Neutral" /// 4 "Agree" 5 "Strongly agree" . label values sat agreelbl . list in 1/5 +----------------------------------+ | id gender sat | |----------------------------------| 1. | 1 Male Agree | 2. | 2 Female Strongly agree | 3. | 3 Male Neutral | 4. | 4 Female Agree | 5. | 5 Male Disagree | +----------------------------------+
The underlying data has not changed — gender is still stored as 1s and 2s, and every calculation, if condition, and egen call keeps working against those integers. label values only changes what Stata displays. Run list, nolabel at any point to see the raw codes again.
Why label values takes a varlist, not just one variable
Because a value label is a standalone object, the same one can be attached to several variables in a single command, which is the real point of keeping the two steps separate:
. label define yesnolbl 0 "No" 1 "Yes" . label values married employed insured yesnolbl
Three unrelated yes/no variables now share one label definition instead of three separately-typed copies of the same two strings. If the wording ever needs to change — “Insured” becomes “Has insurance,” say — redefining yesnolbl once with label define yesnolbl 0 "No" 1 "Yes", modify updates every variable that references it, with nothing to re-type per variable. That is the practical payoff of the split: label variable is one label per variable because descriptions genuinely differ column to column; label values is separated from its definition because the same coding scheme routinely repeats across a dataset.
Labeling as a shared-do-file and reproducibility habit
The value of labeling compounds the moment a .dta file or a do-file stops being something only you look at. A dataset saved with variable and value labels attached is self-documenting — a collaborator opening it in Stata, or you re-opening it a year later, sees “Respondent gender” and “Male”/”Female” without needing the original recoding do-file open in a second window. A few habits make that hold up in practice:
- Label immediately after recoding, not before submitting the final draft. Labels attached right after a
recodeorgeneratestep live in the same block of the do-file as the logic that created the variable, so the mapping is documented exactly where a reader needs it. label listshows every value-label definition currently in memory, with its full mapping — useful for auditing a dataset you did not build yourself before trusting its output.label save using labels.do, replacewrites every current label definition out to its own do-file, which is a clean way to version-control labeling separately from the data-cleaning logic, or to re-apply a house label scheme to a new extract.numlabel _all, addprepends the underlying numeric code to every value label in the dataset at once (so “Agree” becomes “4 Agree”) — a fast way to keep the human-readable text and the raw code both visible in output without giving up either.- Value labels only attach to numeric variables. A string variable already stores its own text, so
label valueshas nothing to do there — if a field needs both a compact numeric code for analysis and readable text for output, encode it as numeric with a value label rather than leaving it as a string.
None of this is enforced by Stata — an unlabeled do-file runs and produces output exactly as a labeled one does. The cost of skipping it shows up later, in someone else’s session, not your own.
Frequently asked questions
Do value labels change the underlying data?
No. label values only changes how Stata displays a variable; the stored values are still the original integers, and every command that operates on the data — summarize, regress, an if qualifier — uses those integers regardless of whether a label is attached. Add , nolabel to most display commands (list, nolabel, tab var, nolabel) to see the raw codes at any time.
Can the same value label be used on more than one variable?
Yes — that is the reason label define and label values are separate commands. Define the mapping once, then attach it to as many variables as share that coding scheme with label values var1 var2 var3 lblname.
What does the modify option on label define do?
Without modify, running label define again on a label name that already exists replaces the entire definition. With , modify, it adds or updates only the value/text pairs you list, leaving the rest of the existing definition untouched — the safer option when you are extending a label set rather than starting it over.
Can a string variable have a value label?
No. Value labels map integers to text, so they only attach to numeric variables. A string variable already holds its own readable text directly.
How do I find out what labels already exist in a dataset I did not create?
label dir lists the names of every value-label set stored in the dataset; label list shows the full mapping for each; codebook shows both variable and value labels alongside summary statistics for every variable at once.
Do labels get saved with the dataset, or do I have to reapply them each session?
They are saved with the data. Once you run save, replace after labeling, every variable and value label is stored inside the .dta file itself and loads automatically the next time anyone opens it — no separate do-file needs to run first, though keeping the labeling do-file around is still good practice for auditing or reapplying the scheme to a new extract.
Related reading
For the broader syntax of reshaping and aggregating a labeled dataset, see CASRAI’s guide to the collapse command in Stata and the append command in Stata — both preserve value labels on by-group and stacking variables. For choosing Stata over the alternatives in the first place, see CASRAI’s SPSS vs. Stata comparison and R vs. Stata comparison. For running the analyses labeled variables typically feed into, see running a t-test in Stata and regression in Stata. For the broader landscape of tools covered here, see the Research Tools & Software hub.








