Thanks to Kit Baum, a program -mydays- by Scott Merryman and
myself has been added to the -mylabels- package on SSC.
-mydays- requires Stata 9. (The rest of the package requires
only Stata 8.)
This program came about in the following way. On 2nd August,
Eric Wruck posted a query under the heading "Axis label
> I'm working on some overlaid graphs where the x-axis is the date.
> The date within the Stata file is always the last day of the month.
> However, when I go to create my -twoway graph-, Stata labels the
> axes with dates that are the first day of the month (e.g., 01
> Oct 00) --
> dates that are not actually found on any record within the file.
> Why does Stata do this? I will try re-formatting the dates but it
> doesn't seem to me that I should have to do this. Any thoughts?
Scott Merryman then posted some code, and I then posted a program
-lastdays- based on Scott's work. (The thread also contains non-official
explanations of why official Stata does what Eric reports.)
Collaboration offstage, and some further thought, led to the program
-mydays-, which is not much more complicated, but is more general.
(There is probably a principle here: Write a program to handle a
messy problem, which is a real pain to tackle interactively. Then
consider how to generalise the program. The more general program
may not be much longer. Occasionally it is shorter!)
-mydays- displays a formatted list of specified days that lie within the
range of a -tsset- daily date variable describing a time series and puts
the numeric version of that list in a specified local macro. The result
may be useful for specifying axis label or tick positions on graphs of
(In the examples that follow, the display is suppressed, just like
the graphs you would get.)
Otherwise put, to use -mydays, you must have a time series dataset defined
by a daily date variable. If it has not been done previously, you must -tsset-.
. sysuse sp500, clear
. tsset date
In this case, the dataset covers dates 2 January 2001 to 31 December 2001.
Now if you ask for a time series graph, Stata by default uses its best guess
at some "nice" dates as labelled dates on the time axis, in this case 1
January 2001, 1 April 2001, 1 July 2001, 1 October 2001, 1 January 2002.
This can be seen in graphs like
. tsline high low
Now suppose that -- like Eric with his problem -- you do not like that
default. In principle you just need to spell out which days you want,
but that can be tedious. Differing month lengths and the existence of
leap years mean that what you want is unlikely to be a regularly spaced
series of days. (Stata has the concept of a datelist, but it doesn't help
here, so far as I can see.)
-mydays- offers an alternative. Unless it is obvious otherwise, it takes
the -tsset- time variable to be a daily date. Suppose that, roughly
like Eric, you want the last days of each quarter. You can type
. mydays, last months(3(3)12) local(last)
. tsline high low, xla(`last', format(%dn_d))
The argument to -months()- here is evidently a numlist.
The process thus entails two steps: define the days you want with -mydays-,
and then feed the name of the macro containing them to the graph command,
here -tsline-. Users of -mylabels- and -myticks- will be familiar with
In this case, -mydays- does not show 31 December 2000, as it
is not within the range of the data, but that could be added on the fly:
. tsline high low, xla(`=mdy(12,31,2000)' `last', format(%dn_d))
If one label per quarter seemed rather sparse labelling, we could
change the frequency to once every two months, by overwriting the
macro and then repeating the graph call:
. mydays, last months(2(2)12) local(last)
. tsline high low, xla(`last', format(%dn_d))
(Note to programmers: calculating last days of months in terms of
the first day of the following month, minus 1, or
mdy(#,1,#) - 1
avoids ringing the changes on 28, 29, 30 and 31 days in each month
and on ordinary and leap years.)
For days other than the last of each month, you need to specify an
argument for the -days()- option. (More generally, at least one of
the -days()- and -last- options must be specified.)
With the same data, we could put ticks at the beginning of
each month and a month label centred on the middle of each month
(modulo a smidgen):
. mydays, day(1) local(ticks)
. mydays, day(15) local(labels)
. tsline high low, xla(`labels', labsize(*0.9) notick format(%dm))
xtic(`=mdy(1,1,2001)' `ticks' `=mdy(1,1,2002)')
Thus the x axis appears roughly like this:
| Jan | Feb | Mar | Apr | May | and so forth
Note that the -months()- option defaults to all the months 1/12.
There is, naturally, more nitty-gritty in the help file.
The generalisation is -mydates- is possible, but not obviously
needed so much as is -mydays-.
* For searches and help try: