Stata连享会 主页 || 视频 || 推文 || 知乎 || Bilibili 站
温馨提示: 定期 清理浏览器缓存,可以获得最佳浏览体验。
New!
lianxh
命令发布了:
随时搜索推文、Stata 资源。安装:
. ssc install lianxh
详情参见帮助文件 (有惊喜):
. help lianxh
连享会新命令:cnssc
,ihelp
,rdbalance
,gitee
,installpkg
✌ 课程详情:
⛳ 课程主页:
⛳ Stata 系列推文:
作者:鞠瑶蕾 (吉林大学)
邮箱:1045751085@qq.com
编者按:本文主要整理自下文,特此致谢!
Source:Cox N J. Stata tip 145: Numbering weeks within months[J]. The Stata Journal, 2022, 22(1): 224-230. -PDF-
目录
研究者们想通过一个变量来计算出每天属于哪个月的哪个周,这件事充满挑战。因为他们既需要解决周的不同含义,又要根据研究设计编辑 Stata 代码。Cox (2010,2012a,2012b,2018b,2019) 说明了一些日期和时间的注意事项。
Stata 对周的设定比较特殊:一年的第一个周从 1 月 1 日开始,第二个周从 1 月 8 日开始,以此类推,每周 7 天,12 月 31 日的时候 52 个周结束。
Stata 的基础设定中不包含第 53 个周,第 52 个周是 8 天还是 9 天取决于这一年是否为闰年。这样的设定有一个明显的优势,即周总是嵌套在年之内,不会跨年。然而,这个设定在日常生活和工作中似乎很少使用。本文介绍的 Stata 使用技巧正是基于这样一个假设:周的设定条件存在差异。
我们建立一个沙盒数据集,包含 2021 年前三个月的日期,1 月、2 月、3 月的天数分别为 31 天、28 天、31 天,前三个月一共有 90 天 (90=31+28+31)。沙盒数据集的建立过程如下:
. set obs 90
. generate ddate = mdy(12, 31, 2020) + _n
. format ddate %td
. list if inlist(_n, 1, _N)
+-----------+
| ddate |
|-----------|
1. | 01jan2021 |
1. | 31mar2021 |
+-----------+
. generate mdate = mofd(ddate)
. format mdate %tm
本文先介绍一些日期的基本设定知识,以帮助读者理解后续内容。在 Stata 中,日期以整数形式保存,第一个日期是 1960 年 1 月 1 日 (数值为 0)。然后,使用 mdy()
命令获得日期。例如:
. display mdy(12, 31, 2020)
22280
若 1960 年 1 月 1 日对应的数值是 0,那么 2020 年 12 月 31 日对应的数值是 22280。display
命令只是以整数形式呈现日期 (距离 1960 年 1 月 1 日的天数),并不会改变日期的储存状态。
display
命令可以通过以下代码改变日期的呈现形式:
. display %td 22280
31dec2020
%td
是默认的日期显示格式,可以使用 format
命令将变量与呈现形式相关联。本文使用 mofd()
函数来生成 “月+日”,应用 %tm
作为默认的日期格式。ym()
函数能够将年和月组装成一个日期形式,作用类似于 mdy()
。monthly()
用于处理字符串,作用类似于 daily()
。
. display ym(2021, 1)
732
上面的两个例子说明,2021 年 1 月距离 1960 年 1 月 1 日间隔 732 个月,因此 2021 年 1 月的数值是整数 732。
这说明改变日期格式并不会改变实际日期。因此,本文强调改变日期呈现形式不是一种日期转换为另一种日期的方法。
如何设定每个月的周呢?最简单的设定是第一周是第一天到第七天,第二周是第八天到第十四天,以此类推。按照这一设定,每个月通常有 5 周,最后一周是 1 天、2 天还是 3 天主要取决于这个月的天数是 29 天、30 天还是 31 天。此外,非闰年的 2 月天数是 28 天,有四个完整的周。
从 “年+月+日” 中提取 “月” 是一种常见需求,day()
能够提取 “日”,取值是 1 至 31。在此基础上,我们需要借助 ceil()
函数把天数映射到周数。
. generate wofm = ceil(day(ddate)/7)
如上述代码所示,将 day(ddate)
的数值除以 7,结果会是 1/7、2/7、3/7、4/7、5/7、6/7、7/7、8/7,以此类推,直到 31/7。ceil()
函数会向上取整数,因此 1/7 会四舍五入为 1,其他数值同理。
在日期计算中,ceil()
和 floor()
函数经常被忽略,我们应该尽力去使用它们 (Cox,2003,2011,2018a) 。
在执行上述步骤时,可以先将 day(ddate)
的结果放入一个新变量中。然后可以根据除法四舍五入:
. generate day = day(ddate)
. generate wofm = ceil(day/7)
如果研究者们需要一个新变量单独保存日度数据,那么应该像上面这样编写代码,这样做更便于他人理解和使用,然后谨慎地检查结果。
. tabulate mdate wofm
| wofm
mdate | 1 2 3 4 5 | Total
-----------+------------------------------+-------
2021m1 | 7 7 7 7 3 | 31
2021m2 | 7 7 7 7 0 | 28
2021m3 | 7 7 7 7 3 | 31
-----------+------------------------------+-------
Total | 21 21 21 21 6 | 90
上面的结果是正常的,因为 1 月和 3 月是 31 天,包括 4 个完整的周和额外的 3 天,而 2 月只包括 4 个完整的周。进一步地,再仔细检查取值 1 至 5 是否与日历一一对应,代码是否能完全复刻闰年的日期分布情况。
另外一种周的设定可能包括从周日开始到周六结束或从周一开始到周日结束。不同地区对周的定义各不相同,这点应尤其注意。例如,多年来,我所在的大学有一个惯例,第一学期的教学周从周四到周三,其他学期的教学周从周一到周五,这样做的目的是安排每学年开始的入学欢迎仪式和相关活动。
接下来,本文介绍一个通用的代码使用技巧,可以涵盖所有周的设定情况。Stata 有一个函数 dow()
,周日的取值为 0,周一取值为 1,以此类推,直到周六取值为 6。接下来,我们假设周日是每周的第一天。
. bysort mdate (ddate): generate WOFM = sum(dow(ddate) == 0)
为了让变量取值与周的设定相符,本文使用 bysort
命令,在每个月单独计算取值。冒号后面的代码是为了计算本月距离现在的周日次数。
dow(date)
在周日等于 0,其他日子不等于 0。当 dow(ddate)==0
时,则返回数值 1;当 dow(ddate)!=0
时,则返回数值 0。sum()
函数可以计算 1 和 0 的加总。Mata 中也有类似函数 runningsum()
,在有些情况下,加总的值被称为cusums,这个术语既有优点也有缺点,通常不在 Stata 中使用。
在每个月的开头,dow(ddate)==0
的取值有 0 和 1 两种情况。在同一个月份,每周的周日都取值为 1,其他日子取值为 0。接下来,本文展示这一命令在上文创建的沙盒数据集中的效果:
. tabulate mdate WOFM
| WOFM
mdate | 0 1 2 3 4 5 |Total
-----------+------------------------------------+-----
2021m1 | 2 7 7 7 7 1 | 31
2021m2 | 6 7 7 7 1 0 | 28
2021m3 | 6 7 7 7 4 0 | 31
-----------+------------------------------------+-----
Total | 14 21 21 21 12 1 | 90
将上述结果与 2021 年前三个月对比发现,每个月的第一个星期天分别是 1 月 3 日、2 月 7 日和 3 月 7 日。相应地,每个月都以一个不完整的周 (非周日) 开始,因此每个月的开头的取值均为 0。以此类推发现,2021 年 8 月是从周日开始的,因此 8 月的第一天取值为 1。
这是一个通用的编码。如果一个周从周一开始周日结束,那么可以通过改变 dow()
的取值实现,即 dow(ddate)
是否等于1。如果希望周的取值从 1 开始,可以在计算 wofm
时加 1。
. by mdate: replace WOFM = WOFM + 1 if WOFM[1] == 0
考虑到不同国家和学科领域对日历的设定不同,周的设定可能存在其他的情况。本文在这里只是提供一个通用的技巧,帮助有需要的研究者实现研究设计。
日期数据是复杂的:实际生活中存在着各式各样的日期规则,但是 Stata 在日期处理方面仍然面临一系列新的挑战,其他软件通过一个或多个不同的数据或变量类型来处理日期。Stata 以整数形式简化了日期的呈现,但仍然需要研究者充分掌握格式和函数的细节,在这方面,help datetime
可能是一个好的开始。
函数很重要:精确处理日期数据的关键是要了解 Stata 的函数,这里不仅包括日期函数 (如 day()
或 dow()
) ,还包括其他通用函数 (如 sum()
或 ceil()
)。
沙盒数据集很有用:部分研究者经常将大型而复杂的数据集读入内存,却缺少具体的处理代码。此时,可以备份或创建一个小型的沙盒数据集 (sandbox dataset) ,就像上文中设计的那样,可以快速得到结果并与正确答案比较。此外,可以使用 display
去呈现单个值或将Mata作为数据美化器。
Note:产生如下推文列表的 Stata 命令为:
lianxh 日期 时间, m
安装最新版lianxh
命令:
ssc install lianxh, replace
免费公开课
最新课程-直播课
专题 | 嘉宾 | 直播/回看视频 |
---|---|---|
⭐ 最新专题 | 文本分析、机器学习、效率专题、生存分析等 | |
研究设计 | 连玉君 | 我的特斯拉-实证研究设计,-幻灯片- |
面板模型 | 连玉君 | 动态面板模型,-幻灯片- |
面板模型 | 连玉君 | 直击面板数据模型 [免费公开课,2小时] |
⛳ 课程主页
⛳ 课程主页
关于我们
课程, 直播, 视频, 客服, 模型设定, 研究设计, stata, plus, 绘图, 编程, 面板, 论文重现, 可视化, RDD, DID, PSM, 合成控制法
等
连享会小程序:扫一扫,看推文,看视频……
扫码加入连享会微信群,提问交流更方便
✏ 连享会-常见问题解答:
✨ https://gitee.com/lianxh/Course/wikis
New!
lianxh
命令发布了:
随时搜索连享会推文、Stata 资源,安装命令如下:
. ssc install lianxh
使用详情参见帮助文件 (有惊喜):
. help lianxh