Thanks as always to Kit Baum, a small utility myweeks is now downloadable from SSC. Stata 8.2 is required.
myweeks addresses a need that arises more often than it is expressed, handling weekly data with a definition of weekly dates more flexible than Stata's own definition. The idea is old and goes back at least to a Stata Journal Tip in 2010 and quite possibly earlier. Some readers may appreciate the wrapping of a command and a help file.
That said, there are many definitions of week and this command doesn't promise to do anything more than is documented.
myweeks takes a numeric daily date variable assumed to follow Stata's rule that daily
dates are integers counted from 0 at 1 January 1960 and generates a new variable
numbering the distinct weeks in which they occur with distinct integers.
myweeks uses the following rules.
1. Each week starts on a particular day of the week, one of Sunday to Saturday.
2. By default weeks start on Sundays, for which the Stata function dow() returns 0.
You may choose a different day to start the week by specifying an option dowstart() with an
integer between 1 (meaning Monday) and 6 (meaning Saturday).
3. By default myweeks uses a rule broadly similar to those used in official Stata:
the first complete week within 1960 using the rules so far is numbered 0. This is
best explained by example. 1 January 1960, daily date 0, was a Friday for which
dow() returns 5. So 2 January 1960 was a Saturday and 3 January 1960 was a Sunday.
Hence week 0 starts on 3 January 1960 if weeks start on day of the week 0, meaning
Sunday. Similarly week 0 starts on 4, 5, 6, 7 January if weeks start on days of
the week 1, 2, 3, 4, but on 1, 2 January if weeks start in days of the week 5, 6.
Any previous weeks in the data are indexed with negative integers. Any later weeks
are indexed with positive integers.
4. Optionally you may specify using the dailydate option that weeks as defined here
are indexed by the daily dates that start them. Such week indexes differ by
multiples of 7. Users proceeding to tsset or xtset will often find it essential in
due course to specify the option delta(7).
Dates in Stata are complicated because dates are complicated. You may have been
familiar long since with many of the rules governing the calendar, but that should not
lead you to suppose that working with dates will always be simple. There are many
different date conventions and Stata may need to be told about yours. Weeks are
especially complicated because several definitions are in use, implying different code
both for identifying weeks and for working with weekly data for weekly dates or for any
other dates.
Stata's official functionality for weeks hinges on an idiosyncratic definition: week 1
of any year always starts on 1 January in that year and subsequent weeks in the same
year start at multiples of 7 days later, except that week 52 is always 8 or 9 days
long. No week 53 is ever observed. This definition is documented, but many users have
not read the documentation or failed to think through its consequences. Stata's
definition ensures that weeks always nest within years, but it is not consistent with
any other definition of week.
Warning: The whole point of myweeks is to step outside Stata's official functionality
for weeks and to offer an alternative. It is consistent only with Stata's dow()
function and whatever is consistent with that. It neither assumes nor can be used
successfully in conjunction with Stata's own weekly dates; nor with functions such as
yw(), weekly(), week(), dofw() or wofd(); nor with Stata's display formats for weekly
dates. Weeks as numbered by myweeks will often span years, starting in one year and
ending in the next.
myweeks is often redundant. Quite commonly, weekly data arrive indexed by a daily date
variable with values 7 days apart. Such dates may be simply understood and used without
needing to be converted to any other form. In particular, they lend themselves to
easily understood graphics or tabulations. Crucially, however, the time step of 7 days
may need to be explained, as already mentioned.
myweeks does not assume completeness of dates in any sense. You may have daily dates
only for certain days of the week, say weekdays Mondays to Fridays. You may lack data
for public holidays. You may have gaps in your dataset in which certain weeks are
absent and not represented by any daily dates. The command will not be fazed by such
incomplete data.
A preference for defining a week by the day of the week on which it ends can be met
with two simple twists. For example, weeks defined to end on Fridays necessarily start
on Saturdays and each ending Friday is 6 days later than the starting Saturday.
This point is developed in the code examples.
You may seek a numbering scheme that differs from what is provided by myweeks. Other
than writing your own code, that is best achieved by following this command with
summarize and adjusting your numbering using the minimum shown, accessible as r(min).
No such option is provided here to emphasize that any such variation is your
responsibility. At the risk of stating the obvious: If you are using different datasets
that you will eventually append or merge, it is best to change to your own numbering
scheme only when all datasets have been combined. If you use myweeks consistently,
datasets can be combined confidently. In addition, be wary of egen's group() function:
although it helpfully maps a sequence of increasing values to integers 1 up, it will
ignore gaps in any sequence.
Users sometimes want to combine weeks into longer periods, lasting say 2, 3 or 4 weeks.
For such aggregation, my best advice is to use floor() or ceil(). .
Once you have classified daily dates into weeks, you may wish to proceed with some kind
of reduction using that framework, either with or without some other classification,
say into panel or longitudinal data. In addition to official commands such as collapse,
contract, and table, rangestat and rangerun from SSC address certain fairly common
needs.
Examples
In practice, you will usually want just one weekly date variable. The example code goes over the top in generating several.
.
myweeks addresses a need that arises more often than it is expressed, handling weekly data with a definition of weekly dates more flexible than Stata's own definition. The idea is old and goes back at least to a Stata Journal Tip in 2010 and quite possibly earlier. Some readers may appreciate the wrapping of a command and a help file.
That said, there are many definitions of week and this command doesn't promise to do anything more than is documented.
myweeks takes a numeric daily date variable assumed to follow Stata's rule that daily
dates are integers counted from 0 at 1 January 1960 and generates a new variable
numbering the distinct weeks in which they occur with distinct integers.
myweeks uses the following rules.
1. Each week starts on a particular day of the week, one of Sunday to Saturday.
2. By default weeks start on Sundays, for which the Stata function dow() returns 0.
You may choose a different day to start the week by specifying an option dowstart() with an
integer between 1 (meaning Monday) and 6 (meaning Saturday).
3. By default myweeks uses a rule broadly similar to those used in official Stata:
the first complete week within 1960 using the rules so far is numbered 0. This is
best explained by example. 1 January 1960, daily date 0, was a Friday for which
dow() returns 5. So 2 January 1960 was a Saturday and 3 January 1960 was a Sunday.
Hence week 0 starts on 3 January 1960 if weeks start on day of the week 0, meaning
Sunday. Similarly week 0 starts on 4, 5, 6, 7 January if weeks start on days of
the week 1, 2, 3, 4, but on 1, 2 January if weeks start in days of the week 5, 6.
Any previous weeks in the data are indexed with negative integers. Any later weeks
are indexed with positive integers.
4. Optionally you may specify using the dailydate option that weeks as defined here
are indexed by the daily dates that start them. Such week indexes differ by
multiples of 7. Users proceeding to tsset or xtset will often find it essential in
due course to specify the option delta(7).
Dates in Stata are complicated because dates are complicated. You may have been
familiar long since with many of the rules governing the calendar, but that should not
lead you to suppose that working with dates will always be simple. There are many
different date conventions and Stata may need to be told about yours. Weeks are
especially complicated because several definitions are in use, implying different code
both for identifying weeks and for working with weekly data for weekly dates or for any
other dates.
Stata's official functionality for weeks hinges on an idiosyncratic definition: week 1
of any year always starts on 1 January in that year and subsequent weeks in the same
year start at multiples of 7 days later, except that week 52 is always 8 or 9 days
long. No week 53 is ever observed. This definition is documented, but many users have
not read the documentation or failed to think through its consequences. Stata's
definition ensures that weeks always nest within years, but it is not consistent with
any other definition of week.
Warning: The whole point of myweeks is to step outside Stata's official functionality
for weeks and to offer an alternative. It is consistent only with Stata's dow()
function and whatever is consistent with that. It neither assumes nor can be used
successfully in conjunction with Stata's own weekly dates; nor with functions such as
yw(), weekly(), week(), dofw() or wofd(); nor with Stata's display formats for weekly
dates. Weeks as numbered by myweeks will often span years, starting in one year and
ending in the next.
myweeks is often redundant. Quite commonly, weekly data arrive indexed by a daily date
variable with values 7 days apart. Such dates may be simply understood and used without
needing to be converted to any other form. In particular, they lend themselves to
easily understood graphics or tabulations. Crucially, however, the time step of 7 days
may need to be explained, as already mentioned.
myweeks does not assume completeness of dates in any sense. You may have daily dates
only for certain days of the week, say weekdays Mondays to Fridays. You may lack data
for public holidays. You may have gaps in your dataset in which certain weeks are
absent and not represented by any daily dates. The command will not be fazed by such
incomplete data.
A preference for defining a week by the day of the week on which it ends can be met
with two simple twists. For example, weeks defined to end on Fridays necessarily start
on Saturdays and each ending Friday is 6 days later than the starting Saturday.
This point is developed in the code examples.
You may seek a numbering scheme that differs from what is provided by myweeks. Other
than writing your own code, that is best achieved by following this command with
summarize and adjusting your numbering using the minimum shown, accessible as r(min).
No such option is provided here to emphasize that any such variation is your
responsibility. At the risk of stating the obvious: If you are using different datasets
that you will eventually append or merge, it is best to change to your own numbering
scheme only when all datasets have been combined. If you use myweeks consistently,
datasets can be combined confidently. In addition, be wary of egen's group() function:
although it helpfully maps a sequence of increasing values to integers 1 up, it will
ignore gaps in any sequence.
Users sometimes want to combine weeks into longer periods, lasting say 2, 3 or 4 weeks.
For such aggregation, my best advice is to use floor() or ceil(). .
Once you have classified daily dates into weeks, you may wish to proceed with some kind
of reduction using that framework, either with or without some other classification,
say into panel or longitudinal data. In addition to official commands such as collapse,
contract, and table, rangestat and rangerun from SSC address certain fairly common
needs.
Examples
Code:
. clear . set obs 42 . * sandbox: first 21 days of 1960; 21 days centred on current date . gen date = mdy(1, _n, 1960) in 1/21 . replace date = daily("$S_DATE", "DMY") + (_n - 32) in 22/42 . format date %td . gen dow = dow(date) . gen which = _n > 21 . * week numbers starting each day of the week . forval d=0/6 { . myweeks date, gen(w`d') dowstart(`d') . myweeks date, gen(W`d') dowstart(`d') daily . local show `show' w`d' W`d' . } . list date dow `show', sepby(which w0) . * weeks ending Friday . myweeks date, gen(wef) dowstart(6) . myweeks date, gen(WEF) dowstart(6) dailydate . replace WEF = WEF + 6 . list date dow wef WEF, sepby(which wef)
.
Code:
. list date dow `show', sepby(which w0) +------------------------------------------------------------------------------------------------------------------------------------------------------+ | date dow w0 W0 w1 W1 w2 W2 w3 W3 w4 W4 w5 W5 w6 W6 | |------------------------------------------------------------------------------------------------------------------------------------------------------| 1. | 01jan1960 5 -1 27dec1959 -1 28dec1959 -1 29dec1959 -1 30dec1959 -1 31dec1959 0 01jan1960 -1 26dec1959 | 2. | 02jan1960 6 -1 27dec1959 -1 28dec1959 -1 29dec1959 -1 30dec1959 -1 31dec1959 0 01jan1960 0 02jan1960 | |------------------------------------------------------------------------------------------------------------------------------------------------------| 3. | 03jan1960 0 0 03jan1960 -1 28dec1959 -1 29dec1959 -1 30dec1959 -1 31dec1959 0 01jan1960 0 02jan1960 | 4. | 04jan1960 1 0 03jan1960 0 04jan1960 -1 29dec1959 -1 30dec1959 -1 31dec1959 0 01jan1960 0 02jan1960 | 5. | 05jan1960 2 0 03jan1960 0 04jan1960 0 05jan1960 -1 30dec1959 -1 31dec1959 0 01jan1960 0 02jan1960 | 6. | 06jan1960 3 0 03jan1960 0 04jan1960 0 05jan1960 0 06jan1960 -1 31dec1959 0 01jan1960 0 02jan1960 | 7. | 07jan1960 4 0 03jan1960 0 04jan1960 0 05jan1960 0 06jan1960 0 07jan1960 0 01jan1960 0 02jan1960 | 8. | 08jan1960 5 0 03jan1960 0 04jan1960 0 05jan1960 0 06jan1960 0 07jan1960 1 08jan1960 0 02jan1960 | 9. | 09jan1960 6 0 03jan1960 0 04jan1960 0 05jan1960 0 06jan1960 0 07jan1960 1 08jan1960 1 09jan1960 | |------------------------------------------------------------------------------------------------------------------------------------------------------| 10. | 10jan1960 0 1 10jan1960 0 04jan1960 0 05jan1960 0 06jan1960 0 07jan1960 1 08jan1960 1 09jan1960 | 11. | 11jan1960 1 1 10jan1960 1 11jan1960 0 05jan1960 0 06jan1960 0 07jan1960 1 08jan1960 1 09jan1960 | 12. | 12jan1960 2 1 10jan1960 1 11jan1960 1 12jan1960 0 06jan1960 0 07jan1960 1 08jan1960 1 09jan1960 | 13. | 13jan1960 3 1 10jan1960 1 11jan1960 1 12jan1960 1 13jan1960 0 07jan1960 1 08jan1960 1 09jan1960 | 14. | 14jan1960 4 1 10jan1960 1 11jan1960 1 12jan1960 1 13jan1960 1 14jan1960 1 08jan1960 1 09jan1960 | 15. | 15jan1960 5 1 10jan1960 1 11jan1960 1 12jan1960 1 13jan1960 1 14jan1960 2 15jan1960 1 09jan1960 | 16. | 16jan1960 6 1 10jan1960 1 11jan1960 1 12jan1960 1 13jan1960 1 14jan1960 2 15jan1960 2 16jan1960 | |------------------------------------------------------------------------------------------------------------------------------------------------------| 17. | 17jan1960 0 2 17jan1960 1 11jan1960 1 12jan1960 1 13jan1960 1 14jan1960 2 15jan1960 2 16jan1960 | 18. | 18jan1960 1 2 17jan1960 2 18jan1960 1 12jan1960 1 13jan1960 1 14jan1960 2 15jan1960 2 16jan1960 | 19. | 19jan1960 2 2 17jan1960 2 18jan1960 2 19jan1960 1 13jan1960 1 14jan1960 2 15jan1960 2 16jan1960 | 20. | 20jan1960 3 2 17jan1960 2 18jan1960 2 19jan1960 2 20jan1960 1 14jan1960 2 15jan1960 2 16jan1960 | 21. | 21jan1960 4 2 17jan1960 2 18jan1960 2 19jan1960 2 20jan1960 2 21jan1960 2 15jan1960 2 16jan1960 | |------------------------------------------------------------------------------------------------------------------------------------------------------| 22. | 31may2024 5 3360 26may2024 3360 27may2024 3360 28may2024 3360 29may2024 3360 30may2024 3361 31may2024 3360 25may2024 | 23. | 01jun2024 6 3360 26may2024 3360 27may2024 3360 28may2024 3360 29may2024 3360 30may2024 3361 31may2024 3361 01jun2024 | |------------------------------------------------------------------------------------------------------------------------------------------------------| 24. | 02jun2024 0 3361 02jun2024 3360 27may2024 3360 28may2024 3360 29may2024 3360 30may2024 3361 31may2024 3361 01jun2024 | 25. | 03jun2024 1 3361 02jun2024 3361 03jun2024 3360 28may2024 3360 29may2024 3360 30may2024 3361 31may2024 3361 01jun2024 | 26. | 04jun2024 2 3361 02jun2024 3361 03jun2024 3361 04jun2024 3360 29may2024 3360 30may2024 3361 31may2024 3361 01jun2024 | 27. | 05jun2024 3 3361 02jun2024 3361 03jun2024 3361 04jun2024 3361 05jun2024 3360 30may2024 3361 31may2024 3361 01jun2024 | 28. | 06jun2024 4 3361 02jun2024 3361 03jun2024 3361 04jun2024 3361 05jun2024 3361 06jun2024 3361 31may2024 3361 01jun2024 | 29. | 07jun2024 5 3361 02jun2024 3361 03jun2024 3361 04jun2024 3361 05jun2024 3361 06jun2024 3362 07jun2024 3361 01jun2024 | 30. | 08jun2024 6 3361 02jun2024 3361 03jun2024 3361 04jun2024 3361 05jun2024 3361 06jun2024 3362 07jun2024 3362 08jun2024 | |------------------------------------------------------------------------------------------------------------------------------------------------------| 31. | 09jun2024 0 3362 09jun2024 3361 03jun2024 3361 04jun2024 3361 05jun2024 3361 06jun2024 3362 07jun2024 3362 08jun2024 | 32. | 10jun2024 1 3362 09jun2024 3362 10jun2024 3361 04jun2024 3361 05jun2024 3361 06jun2024 3362 07jun2024 3362 08jun2024 | 33. | 11jun2024 2 3362 09jun2024 3362 10jun2024 3362 11jun2024 3361 05jun2024 3361 06jun2024 3362 07jun2024 3362 08jun2024 | 34. | 12jun2024 3 3362 09jun2024 3362 10jun2024 3362 11jun2024 3362 12jun2024 3361 06jun2024 3362 07jun2024 3362 08jun2024 | 35. | 13jun2024 4 3362 09jun2024 3362 10jun2024 3362 11jun2024 3362 12jun2024 3362 13jun2024 3362 07jun2024 3362 08jun2024 | 36. | 14jun2024 5 3362 09jun2024 3362 10jun2024 3362 11jun2024 3362 12jun2024 3362 13jun2024 3363 14jun2024 3362 08jun2024 | 37. | 15jun2024 6 3362 09jun2024 3362 10jun2024 3362 11jun2024 3362 12jun2024 3362 13jun2024 3363 14jun2024 3363 15jun2024 | |------------------------------------------------------------------------------------------------------------------------------------------------------| 38. | 16jun2024 0 3363 16jun2024 3362 10jun2024 3362 11jun2024 3362 12jun2024 3362 13jun2024 3363 14jun2024 3363 15jun2024 | 39. | 17jun2024 1 3363 16jun2024 3363 17jun2024 3362 11jun2024 3362 12jun2024 3362 13jun2024 3363 14jun2024 3363 15jun2024 | 40. | 18jun2024 2 3363 16jun2024 3363 17jun2024 3363 18jun2024 3362 12jun2024 3362 13jun2024 3363 14jun2024 3363 15jun2024 | 41. | 19jun2024 3 3363 16jun2024 3363 17jun2024 3363 18jun2024 3363 19jun2024 3362 13jun2024 3363 14jun2024 3363 15jun2024 | 42. | 20jun2024 4 3363 16jun2024 3363 17jun2024 3363 18jun2024 3363 19jun2024 3363 20jun2024 3363 14jun2024 3363 15jun2024 | +------------------------------------------------------------------------------------------------------------------------------------------------------+ .. list date dow wef WEF, sepby(which wef) +------------------------------------+ | date dow wef WEF | |------------------------------------| 1. | 01jan1960 5 -1 01jan1960 | |------------------------------------| 2. | 02jan1960 6 0 08jan1960 | 3. | 03jan1960 0 0 08jan1960 | 4. | 04jan1960 1 0 08jan1960 | 5. | 05jan1960 2 0 08jan1960 | 6. | 06jan1960 3 0 08jan1960 | 7. | 07jan1960 4 0 08jan1960 | 8. | 08jan1960 5 0 08jan1960 | |------------------------------------| 9. | 09jan1960 6 1 15jan1960 | 10. | 10jan1960 0 1 15jan1960 | 11. | 11jan1960 1 1 15jan1960 | 12. | 12jan1960 2 1 15jan1960 | 13. | 13jan1960 3 1 15jan1960 | 14. | 14jan1960 4 1 15jan1960 | 15. | 15jan1960 5 1 15jan1960 | |------------------------------------| 16. | 16jan1960 6 2 22jan1960 | 17. | 17jan1960 0 2 22jan1960 | 18. | 18jan1960 1 2 22jan1960 | 19. | 19jan1960 2 2 22jan1960 | 20. | 20jan1960 3 2 22jan1960 | 21. | 21jan1960 4 2 22jan1960 | |------------------------------------| 22. | 31may2024 5 3360 31may2024 | |------------------------------------| 23. | 01jun2024 6 3361 07jun2024 | 24. | 02jun2024 0 3361 07jun2024 | 25. | 03jun2024 1 3361 07jun2024 | 26. | 04jun2024 2 3361 07jun2024 | 27. | 05jun2024 3 3361 07jun2024 | 28. | 06jun2024 4 3361 07jun2024 | 29. | 07jun2024 5 3361 07jun2024 | |------------------------------------| 30. | 08jun2024 6 3362 14jun2024 | 31. | 09jun2024 0 3362 14jun2024 | 32. | 10jun2024 1 3362 14jun2024 | 33. | 11jun2024 2 3362 14jun2024 | 34. | 12jun2024 3 3362 14jun2024 | 35. | 13jun2024 4 3362 14jun2024 | 36. | 14jun2024 5 3362 14jun2024 | |------------------------------------| 37. | 15jun2024 6 3363 21jun2024 | 38. | 16jun2024 0 3363 21jun2024 | 39. | 17jun2024 1 3363 21jun2024 | 40. | 18jun2024 2 3363 21jun2024 | 41. | 19jun2024 3 3363 21jun2024 | 42. | 20jun2024 4 3363 21jun2024 | +------------------------------------+