Also, some commands support numeric lists, or numlists. You can have a numeric list simply as a set of numbers, say 2 3 5 7 11 13 17 19, or as a range 1/11, or as a range with a step 0(5)25, or as any mix of the three.
Now, let's hit for some real stuff.
cd h:\ log using class3, replace sysuse auto reg pri mpg wei for estimates store Model1 reg pri mpg wei for if ~mi(rep) estimates store Model2 reg pri mpg wei for , robust estimates store Model3 reg pri mpg wei for if ~mi(rep), cluster(rep) estimates store Model4 regress pri mpg wei for leng turn displ , cl(rep) regress estimates restore Model3 eret list matrix list e(b) vce count if e(sample) return list di _b[_cons] di _b[wei] di _se[wei] test wei test wei mpg test wei = mpg test (wei + 2*mpg - 0.001*for = 50) (mpg) testnl ln(_b[wei]/_b[mpg])=0 estimates restore Model1 hettest hettest displ gear ovtest ovtest, rhs imtest vif rvfplot, yline(0) rvpplot wei avplots avplot gear lvr2plot , mlab(make) mlabsize(small) xsc( r(0 0.16) )I have added some spaces between commands to make it more readable. This is a reasonably good do-file, and let's see if we can run it. Go to Stata Do-file editor by either typing
Self Check: Did it run? Any error messages? |
But here's what we can do to make it more readable.
Now, have a look at
my resulting do-file: class3.do on the web page. Take a minute
to run it now. You can do it by either downloading it to your local directory, or by
clear
set memory 1m
capture log close
version 8
The mission of capture is to preserve Stata from stopping in case there
is an error. Here, an error would arise if there were no log file were open, and hence
no log file to be closed. A couple of other relevant commands that you might find useful in
your programs are quietly and its counterpart noisily. The former
simply suppresses output but does stop for errors, unlike capture, and the latter turns
out output temporarily. Try this piece of code:
qui {
di 1
noi di 2
cap di #
cap noi di !
}
The first line was swallowed by the quietly that works on the whole block given
by the curly brackets. The second one was indeed shown by Stata. The next two lines would
have returned errors of invalid syntax if they were not preceded by capture (try
them without capture to see what happens). In the last line, however, the noisily
statement turned the output back on, so we saw what happened.
Finally, the version command tells Stata that everything to follow
was written with Stata 8 in mind. Just a precaution for future work with maybe
Stata 11 if it becomes a totally different animal...
log close
exit
set more on
more
set more off
The first command sets more to the state where it stops if Stata has to show
more than one screen of output, or if more command is issued explicitly. The last
one sets more to the state where it disregards more or long outputs. This
is often helpful in long files! (Another way to deal with long outputs if you see a lot of
--more-- messages is to press and hold spacebar so that Stata
will have enough of spaces to use up, or press Break... and enter set more off in the
header of your do-file or in the command line.)
. do http://www.duke.edu/~skolenik/class3.do
clear do r15dac-clean do r16dac-clean do r15r16dac-combine do r15r16dac-regressions exit
Also, you can launch Stata in the background mode and instruct it to run a specified
do-file by typing something like
There is not that much repetition of the same thing over and over again in that file, but here's the
central piece I'd like to focus on for now (omitting estimates store ... and more
commands):
Now let me get to a killer question: suppose you had to remove a variable from the regressor list,
or add another one to the model. Here, you would have to go across four lines of your do-file code
to modify it. If you had 150 lines (and I've seen do-files with even greater number of regressions,
don't ask me for the reason why somebody wanted to run 150 regressions at a time), you'll make at least one error
as you get around. Is there a neat solution?
Well, I wouldn't ask this rhetorical question in a tutorial if there were no neat answer.
And the answer is, "Use local macros".
An important (and in fact extremely powerful rather than annoying) property of the local macros,
and the reason they are called "local", is that they only exist within the process where they were defined.
A process may be your interactive Stata session, your do-file, or your programs
(and Stata has a very specific definition of what a program is; you probably should not refer to
your do-files as programs, although most people would refer to the art of writing ones as
programming. We'll get to a real program by the end of this tutorial).
If you have two local macros
of the same name in two different processes, those will be different objects to Stata.
If you wanted to create a string that you would need to use in different processes
(say more than one do-file, plus an interactive session), you can use global command
to create a global macro. The global macros are referred to with a dollar sign:
Going back to our example, specifying reg pri `reglist' etc. made it really simple
to introduce modifications to the list of regressors. If we want to exclude mpg that
was not significant in any of the regressions, all we need to do now is to exclude it from
a single local definition:
Supposes I wanted to perform a certain action on the list of variables, say take logs.
The brute force method of doing this will involve something like
Stata cycles handle such jobs as follows.
Here is example of another cycle command:
A few more intricate examples are given at
UCLA Academic Technologies Services Stata website.
wstata /b do dofilename
in Windows, or
stata -b do dofilename
in Unix. (On some Unix servers that have special background job management tools,
you might need to submit your job to a special queue to be executed. Contact your Unix
administrator to find out the details.) In the background mode, Stata will redirect all output
into the file dofilename.log.
Local and global macros
Knowing how to write and run a do-file is in fact a very small part of actually mastering
Stata programming skills. Let us revisit some of the class3.do elements and see how
those can be dealt with more efficiently.
reg pri mpg wei for
reg pri mpg wei for if ~mi(rep)
reg pri mpg wei for , robust
reg pri mpg wei for , cluster(rep)
We are entering the same command, the same list of variables, and only change options and
selection criteria. How can we automate that? Historically, we were pressing PgUp key
on the keyboard (Ctrl+R in UNIX) and entered some modifications to the previous command
(and later copied and pasted it into the do-file). What if you had to write it from scratch?
The answer will probably again be that you copied and pasted the a command you entered
into the appropriate spaces.
local reglist mpg wei for
reg pri `reglist'
reg pri `reglist' if ~mi(rep)
reg pri `reglist' , robust
reg pri `reglist' , cluster(rep)
The local macro is defined by the command local, and simply is a string of characters.
If you typed the above sequence in Stata by copying the whole five lines and pasting it
into Stata command prompt, you can try
. di "`reglilst'"
to see what is in there. If you had it in your do-file (try it too! You can go to the Do-file
editor, open a new document, paste those lines, and then do the current file by going to Tools /
Do, pressing Ctrl+D, or hitting the "Do current" button)
and then you tried it in Stata command prompt, you won't get the answer you expected:
. global reglist mpg wei for
. di "$reglist"
. reg pri $reglist
local reglist wei for
or even
local reglist /* mpg */ wei for
Cycles
In fact, Stata uses local macros on many different occasions. One such occasion that
is directly related to our topic of the ways to avoid repetitions are cycles.
g lprice = log(price)
lab var lprice "Log of price"
g lgear_ratio = log(gear)
lab var lgear "Log of gear_ratio"
g ltrunk = log(trunk)
lab var ltrunk "Log of trunk"
Just to see how tiring this is, type it all in the your Do-file editor without
Copy/Paste utilities. Now, count how many errors you made...
foreach x of varlist price gear trunk {
gen l`x' = log(`x')
lab var l`x' "Log of `x' "
}
Stata's cycle command foreach created the local macro `x' and
consecutively redefined it with the variable names price, gear_ratio and trunk
inside the body of the cycle between the curly brackets. Indentation within the body of the cycle
is not necessary, but it does add a lot of readability to your do-files and programs.
forvalues p = 2/5 {
gen mpg`p' = mpg^`p'
lab var mpg`p' "mpg to power `p' "
}
forvalues used all the values of `p' between 2 and 5 in computing powers
and making labels.
Self Check:
Write a do-file that produces a table
of factorials. Hint: you would need to create a macro before
the forvalues command that would contain the current product of
integers, and update it inside your cycle. The output, as you remember, is
performed by display command. You should be able to fit it into five lines.
Can you reproduce your results with variables and observations? Come up with a generate command and a replace command with some in qualifiers -- you would actually need only two commands to perform it. |
program define hello di "Hello, world!" end exitType it into a new do-file in your Do-file editor, and let's call it hello-program.do. Let's try it:
program define hello di "Hello, world!" end hello exitCan we run it again?
cap pro drop hello program define hello di "Hello, world!" end hello exit
Self Check: why is capture needed here? When would program drop without a capture issue an error message? |
Let us now go back to Class3.do and imagine that we would need to run the four regressions (the basic one, with an if condition, with the robust option and with the cluster option) over different set of variables. Should we copy / paste the code, or should we write a program? Here's an example that is almost as real in handling Stata's local macros as the "official" Stata programs:
cap pro drop checkreg pro def checkreg syntax varlist(numeric min=1) [if] , cluster(passthru) marksample touse reg `varlist' reg `varlist' if `touse' reg `varlist' , robust reg `varlist' , `cluster' endThe syntax command parses whatever follows the checkreg command. The specification here is that it needs:
Let us stop here and review what we've covered in this class:
Back to the list of tutorials and Stata resources
Questions, comments? E-mail me!.
Stas Kolenikov