Skip to main content

Data Analysis with Stata


If you find yourself frequently reusing chunks of code, you might want to write a program for those chunks. For example, suppose you need to generate many graphs that are more or less formatted similarly. Instead of entering the twoway command each time you want a graph, you could write a program for it. When you want a graph, simply call the program.

Note: Work in a do-file if you want to follow along. We will use the system example dataset auto.dta.

Without writing a program, you would do something like this:

sysuse auto, clear
*Scatter plot of price vs mpg
twoway scatter price mpg, title(Price vs MPG)
graph export price_vs_mpg.png, replace

*Scatter plot of price vs foreign
twoway scatter price weight, title(Price vs weight)
graph export price_vs_weight.png, replace

This generates two scatter plots, one for price vs. mpg and the other for price vs. weight.

You could write a program for this, which would save you some space and perhaps some labor (if you need to modify the graphs, you would simply modify the program instead of each individual twoway command).

capture program drop printgraph
program define printgraph
    twoway `1' `2' `3', title(`2' vs `3')
    graph export `2'_vs_`3'.png, replace

A few things:

  • program define printgraph tells Stata that you're writing a program named printgraph and everything that follows is what you want the program to do.
  • I wrote printgraph such that graph type, y-variable and x-variable are passed to it as arguments.
  • Within the program, the arguments passed to it are accessed as macros. The macro `1' refers to the first argument, `2' the second argument and so forth.
  • End marks the end of the program.
  • capture program drop is for convenience. It instructs Stata to ignore the fact that a program named printgraph is already in memory when you rerun the do-file. Without this command, Stata will protest that printgraph already exists.

To produce your graphs, just call printgraph.

Say you want  a histogram of mpg. Stata is very forgiving and doesn't care that in this instance, your program tries to use a macro that doesn't exist (the third one).

The title of the histogram is rather unsatisfactory. You can further generalize the program to provide better titles.

capture program drop printgraph
program define printgraph
    if "`1'" == "histogram" {
        local gtitle = "`1' of `2'"
    else {
        local gtitle = "`1' plot of `2' vs `3'"
    twoway `1' `2' `3', title(`gtitle')
    graph export `1'_`2'_`3'.png, replace

Let's see what this gets us.

Click here for the do-file for this example.

One final note...

If you're passing arguments to your program, it's better to explicitly specify the arguments within the program itself for clarity. You do this with the args command. Below is our example program modified to incorporate the use of args.

capture program drop printgraph
program define printgraph
    args type yvar xvar
    if "`type'" == "histogram" {
        local gtitle = "`type' of `2'"
    else {
        local gtitle = "`type' plot of `yvar' vs `xvar'"
    twoway `type' `yvar' `xvar', title(`gtitle')
    graph export `type'_`yvar'_`xvar'.png, replace