How to use Stata: syntax basics and loading data
Stata is a statistical software package that you control mainly by typing commands, either in the Command window or in a do-file. Nearly all Stata code follows the same structure:
[by varlist:] command [varlist] [if expression] [in range] [weight] [, options]Learn this pattern once and most commands become predictable. Options always come after a single comma. Commands can be abbreviated, so summarize can be typed as sum and tabulate as tab. Type help followed by any command name to open its manual entry.
Loading and saving data
sysuse auto, clear // built-in example dataset
use "mydata.dta", clear // open a Stata dataset
import delimited "survey.csv", clear // import a CSV file
import excel "survey.xlsx", firstrow clear // import Excel, first row as names
save "mydata_clean.dta", replace // save (overwrite if it exists)The clear option discards the data currently in memory, and replace allows Stata to overwrite an existing file. Without them, Stata stops with an error to protect your work.
and, or and other operators in Stata
Conditions in if use == for equals, != for not equal, & for and, | for or, and ! for not.
list make price mpg if foreign == 1 & price > 10000
count if rep78 == 1 | rep78 == 2
summarize price if !missing(rep78)Watch out: Stata treats missing values (.) as larger than any number, so count if rep78 > 3 also counts the five cars with missing repair records. Write count if rep78 > 3 & !missing(rep78) instead.
Exploring data: describe, summarize and finding the median
Start every analysis by checking what is in the dataset.
sysuse auto, clear
describe // variable names, types, labels, number of obs
codebook rep78 // values, missing count, labels for one variable
list make price mpg in 1/5
summarize // obs, mean, sd, min, max for all variables
summarize price mpg weightHow to find the median in Stata
Plain summarize does not show the median. Add the detail option to get percentiles (the 50th percentile is the median), the four largest and smallest values, variance, skewness and kurtosis:
summarize price, detail
display r(p50) // prints the median stored by summarizeAfter any summarize, results are stored in r(); type return list to see them all, including r(mean) and r(sd).
Summary statistics by group
bysort foreign: summarize price mpg
tabstat price mpg weight, statistics(n mean sd median min max)
tabstat price mpg, by(foreign) statistics(mean sd median) columns(statistics)tabstat is the quickest way to build a compact table of means, medians and standard deviations, and the by() option splits it by group. To get a single Stata mean with a confidence interval, use mean price.
Tabulate and tables in Stata
tabulate (or tab) produces frequency tables for categorical variables.
tabulate foreign // one-way frequency table
tabulate rep78, missing // include missing as a category
tabulate rep78 foreign // two-way cross-tabulation
tabulate rep78 foreign, row chi2 // row percentages and chi-square test
tabulate rep78 foreign, column exact // column percentages, Fisher's exact test
tabulate foreign, summarize(price) // mean and sd of price by categoryTo produce every pairwise cross-tab among several variables at once, use tab2. The tab1 command gives separate one-way tables.
tab2 rep78 foreign headroom
tab1 rep78 foreignThe table command
In Stata 17 and later, table builds customizable tables of statistics:
table foreign, statistic(mean price) statistic(sd price)
table rep78 foreign, statistic(frequency)
table foreign, statistic(mean price mpg) nformat(%9.1f)Earlier versions use a different syntax (for example table foreign, contents(mean price sd price)), so check help table for your version.
Creating variables: generate, replace, egen, labels and logs
generate and replace
generate price_k = price / 1000
generate heavy = (weight > 3000) if !missing(weight)
replace price_k = round(price_k, 0.1)
generate mpg_cat = .
replace mpg_cat = 1 if mpg < 20
replace mpg_cat = 2 if mpg >= 20 & mpg < 30
replace mpg_cat = 3 if mpg >= 30 & !missing(mpg)generate creates a new variable; replace changes an existing one. A logical expression such as (weight > 3000) returns 1 if true and 0 if false.
egen for group statistics
egen mean_price = mean(price), by(foreign) // group mean on every row
egen price_q = cut(price), group(4) // quartile groups 0 to 3
egen n_cars = count(price), by(rep78)
egen id = group(foreign rep78) // one id per combinationLogarithms in Stata
Both ln() and log() return the natural logarithm; use log10() for base 10. The log of zero or a negative number is missing.
generate ln_price = ln(price)
generate log10_price = log10(price)Labels and recoding
generate expensive = (price > 10000)
label variable expensive "Price above 10,000 USD"
label define yesno 0 "No" 1 "Yes"
label values expensive yesno
recode rep78 (1 2 = 1 "Poor") (3 = 2 "Average") (4 5 = 3 "Good"), generate(rep3)Concatenating strings
Join strings with +. Numbers must be converted with string() first, or Stata reports a type mismatch.
generate label_mpg = make + " (" + string(mpg) + " mpg)"
decode foreign, generate(origin) // value labels to text
generate make_origin = make + " - " + origin
egen combo = concat(foreign rep78), punct("_") // egen handles numbers tooTo convert between types, use destring (text that holds numbers to numeric), tostring (numeric to text) and encode (text categories to labeled numeric codes).
Merging and appending datasets in Stata
merge adds variables (columns) from another file by matching on key variables. append adds observations (rows). The examples below split auto into pieces and join them back so you can run them.
merge 1:1
Use 1:1 when the key uniquely identifies observations in both files.
sysuse auto, clear
keep make price mpg
save auto_a, replace
sysuse auto, clear
keep make weight length
save auto_b, replace
use auto_a, clear
merge 1:1 make using auto_b
tabulate _mergemerge m:1
Use m:1 when many observations in memory match one observation in the using file, such as adding group-level data to individuals.
sysuse auto, clear
collapse (mean) avg_price = price, by(foreign)
save origin_means, replace
sysuse auto, clear
merge m:1 foreign using origin_means
generate price_gap = price - avg_priceUnderstanding _merge in Stata
| _merge value | Label | Meaning |
|---|---|---|
| 1 | master only (1) | Observation was only in the data in memory |
| 2 | using only (2) | Observation was only in the using file |
| 3 | matched (3) | Observation was found in both files |
Always tabulate _merge and investigate unmatched cases before running drop _merge. If you expect every case to match, let Stata check it for you, or keep only matched rows without creating the variable:
use auto_a, clear
merge 1:1 make using auto_b, assert(match) nogenerateReplace assert(match) with keep(match) to keep only matched rows instead of stopping when some fail to match. If a merge fails with "variable make does not uniquely identify observations in the master data", check for duplicates with duplicates report make.
append
sysuse auto, clear
keep if foreign == 0
save domestic, replace
sysuse auto, clear
keep if foreign == 1
append using domestic
count // back to 74 observations Reshape in Stata: long and wide
reshape converts data between wide format (one row per unit, repeated measures in separate columns) and long format (one row per unit per time point). Panel and repeated-measures commands usually need long format.
clear
input id inc2020 inc2021 inc2022
1 50 52 55
2 40 41 45
3 61 60 64
end
reshape long inc, i(id) j(year) // wide to long
list, sepby(id)
reshape wide inc, i(id) j(year) // long back to wide
listIn reshape long inc, i(id) j(year), inc is the stub shared by the wide variables, i() names the variable that identifies each unit, and j() names the new variable that will hold the suffix (2020, 2021, 2022). If Stata reports that the i() variable does not uniquely identify observations, you have duplicate ids; find them with duplicates list id. If the suffix contains letters, add the string option.
Regression in Stata: regress, robust errors, F tests and logit
The regress command
The syntax is regress, the dependent variable, then the independent variables.
sysuse auto, clear
regress price mpg weight
regress price mpg weight i.foreign // factor variable dummy
regress price mpg weight i.foreign, vce(robust) // robust standard errors
regress price mpg weight ib3.rep78 // category 3 as base
regress price c.mpg##i.foreign // interactionThe prefix i. tells Stata a variable is categorical and creates the dummy variables for you; c. marks a continuous variable in interactions, and ## includes both main effects and the interaction. vce(robust) (or simply , robust) gives heteroskedasticity-robust standard errors; use vce(cluster id) for clustered data.
F statistic and F tests in Stata
The regression header reports the overall F statistic, its p value (Prob > F), R-squared and the number of observations. To test specific restrictions after estimation, use test:
regress price mpg weight i.foreign
test weight // H0: coefficient on weight = 0
test mpg weight // joint F test: both coefficients = 0
test 1.foreign // the foreign dummy
test mpg = weight // equality of two coefficients
regress price mpg weight i.rep78
testparm i.rep78 // joint test of all rep78 dummiespredict after regression
regress price mpg weight
predict yhat // fitted values (linear prediction)
predict resid, residuals // residualsLogit model in Stata
For a binary outcome coded 0/1, use logit. Add or to report odds ratios, or use logistic, which reports odds ratios by default.
logit foreign price mpg
logit foreign price mpg, or
logistic foreign price mpg
predict phat, pr // predicted probability of foreign = 1
margins, dydx(*) // average marginal effectsOrdered logistic regression and its graph
For ordered outcomes such as ratings, use ologit, then graph predicted probabilities with margins and marginsplot:
ologit rep78 price mpg
margins, at(mpg = (15(5)35)) predict(outcome(5))
marginsplotPanel data with xtreg
Panel models need an id and a time variable declared with xtset. The auto data are cross-sectional, so this example uses another official dataset:
webuse nlswork, clear
xtset idcode year
xtreg ln_wage age tenure, fe // fixed effects
xtreg ln_wage age tenure, re // random effectsMultiple imputation in Stata
The mi commands impute missing values and combine results across imputed datasets. Here the five missing values of rep78 are imputed:
sysuse auto, clear
mi set mlong
mi register imputed rep78
mi impute ologit rep78 price mpg weight, add(20) rseed(1234)
mi estimate: regress price mpg weight i.rep78 Stata graphs: scatter plots, line plots, bar graphs and histograms
Scatter plot in Stata
sysuse auto, clear
twoway scatter price mpg
twoway (scatter price mpg) (lfit price mpg) // add fitted line
twoway (scatter price mpg if foreign == 0) (scatter price mpg if foreign == 1), legend(order(1 "Domestic" 2 "Foreign"))
scatter price mpg, mlabel(make) // label pointsLine plot
Line plots connect points in the order of the x variable, so they suit time series. This example uses the built-in U.S. life expectancy data:
sysuse uslifeexp, clear
twoway line le year
twoway line le_male le_female year, legend(order(1 "Male" 2 "Female"))Bar graph
sysuse auto, clear
graph bar (mean) price, over(foreign)
graph bar (mean) mpg, over(rep78) over(foreign)
graph hbar (count) mpg, over(rep78)Histogram with a kdensity curve
histogram mpg
histogram mpg, frequency
histogram mpg, kdensity // overlay kernel density
histogram mpg, kdensity normal // add a normal curve too
histogram mpg, kdensity kdenopts(bwidth(2))
histogram price, by(foreign)The kdensity option overlays a smoothed density estimate; kdenopts() passes options such as bandwidth to it. To save any graph for a paper, run graph export "mpg_hist.png", replace immediately after drawing it.
Do-files and log files: writing reproducible Stata code
A do-file is a plain text file of Stata commands. Open the editor with doedit, write your commands, and run them all with do. Rerunning one file from raw data to final tables is the most reliable way to keep an analysis correct and to document your methods.
* analysis.do - price regressions on the auto data
version 18
clear all
capture log close
log using "analysis.log", replace text
sysuse auto, clear
summarize price mpg weight, detail
tabulate rep78 foreign, row
regress price mpg weight i.foreign, vce(robust)
test mpg weight
log closeNotes on this template:
- Lines starting with
*are comments;//adds a comment at the end of a line, and/* ... */comments out a block. Use///at the end of a line to continue a long command on the next line. versiontells Stata which version's behavior to use; set it to the version you actually run.capture log closecloses any log left open from a previous run without stopping if none is open.log using ..., replace textsaves all output as a readable text file. Close it at the end withlog close.
Run a do-file from the Command window with do analysis.do, or highlight lines in the editor and run only those.
Common Stata errors and how to fix them
| Error message | Typical cause | Fix |
|---|---|---|
| type mismatch r(109) | Comparing or combining a string with a number, e.g. list if make == 1 or generate x = make + mpg | Put string values in quotes (make == "AMC Spirit"), convert with string() or real(), or use destring |
| variable ... already defined r(110) | Running generate for a variable that exists, often when rerunning a do-file | Use replace, run drop varname first, or capture drop varname before generating |
| variable ... not found r(111) | Typo, wrong case (Stata names are case-sensitive) or variable not yet created | Check names with describe or lookfor |
| invalid syntax r(198) | Missing comma before options, unbalanced parentheses or quotes | Compare against the syntax diagram in help command |
| no observations r(2000) | An if condition excludes every case, or a string variable was used in a numeric command | Check the condition with count if ... and variable types with describe |
| not sorted r(5) | Using by varlist: on unsorted data | Use bysort varlist: instead of by varlist: |
| ... does not uniquely identify observations | Duplicate keys in a 1:1 merge (r(459)) or in the i() variable of a reshape | Inspect with duplicates report; use m:1 if appropriate or fix the duplicates |
A pattern that avoids most "already defined" errors when rerunning a do-file:
capture drop ln_price
generate ln_price = ln(price)If your output still looks wrong rather than producing an error, the most common culprit is missing values being included in a > condition. Our Stata help service can review do-files and explain output; you stay the author of your analysis.
Frequently asked questions
What is Stata used for?
Stata is a statistical software package used for data management, statistical analysis and graphics. It is especially common in economics, epidemiology, political science and public health, and is controlled mainly through commands and do-files.
How do I find the median in Stata?
Run summarize varname, detail and read the 50% percentile, or type display r(p50) afterward. You can also use tabstat varname, statistics(median), which also works by group with the by() option.
What does _merge mean in Stata?
_merge is a variable created by merge that records where each observation came from: 1 means only in the master data, 2 only in the using file, and 3 matched in both. Tabulate it to check your merge before dropping it.
How do I run a regression with robust standard errors in Stata?
Add the vce(robust) option, for example regress price mpg weight, vce(robust). For data with clusters such as students within schools, use vce(cluster clustervar) instead.
How do I do an F test in Stata?
After regress, use test followed by the variables, for example test mpg weight for a joint test that both coefficients are zero. Use testparm i.varname to test all dummies of a categorical variable together.
Why do I get a type mismatch error in Stata?
Type mismatch means you mixed string and numeric values, such as comparing a text variable to a number or adding a number to a string. Put string values in quotes or convert the variable with destring, string() or real().
Should I use Stata or R?
Both are capable of almost any analysis. Stata offers consistent, well-documented commands and is standard in some fields, while R is free and extremely flexible but has a steeper learning curve; follow your field's and supervisor's conventions.
Related help and guides
Stata help
Clean do-files, regression and panel models, publication-ready tables.
Statistics help for research
Test selection, analysis in SPSS, R or Stata, results chapters and APA reporting.
Online statistics tutoring
One-to-one stats tutoring from AP Statistics to PhD methods.
Data Analysis in Research: Methods, Steps and Examples
How data analysis works in research: quantitative and qualitative methods, a seven-step process, choosing techniques and writing the analysis section.
Which Statistical Test Should I Use?
Choose the right statistical test by research question, variable type and design: t-tests, ANOVA, chi-square, correlation, regression and more.
Descriptive vs Inferential Statistics
The difference between descriptive and inferential statistics, with examples of mean, median, mode, standard deviation, confidence intervals and common tests.
The t-Test Explained: Formula, Types and Interpretation
What a t-test is, the one-sample, independent and paired formulas, how to find the test statistic and degrees of freedom, and how to report it in APA.