温馨提示: 定期 清理浏览器缓存,可以获得最佳浏览体验。
作者:吴雄 (湘潭大学)
目录
重要声明 (2019.4.16-连玉君):
在实证分析过程中,使用平行面板数据通常是不得已而为之的事情。这是因为,受限于计量理论的发展,有些模型只能应用于平行面板,如 Hansen (1999, JoE) 提出的面板门槛模型;Love and Zicchino (2006, QREF) 文中使用的面板 VAR 模型。事实上,强行把数据处理为平行面板数据,意味着留下来的公司都是上市时间较长、规模较大的公司,基于这些公司得到的结论并不能直接推广到所有公司中。简言之,使用平行面板数据存在一个潜在的风险:我们在数据处理过程中,人为地引入了样本选择偏误问题。因此,如果你使用的模型适用于非平行面板,那么要把尽可能完整的数据纳入样本,而尽力避免人为删减。
之前,我在处理数据的时候,经常碰到一些非平衡面板数据,当时处理完后才发现连玉君老师之前已经编写了一个 xtbalance
的命令,该命令专门用于将连续时间非平衡面板处理成平衡面板。但是,该命令在处理非连续时间的非平衡面板有点缺陷,所以平时我还是自己写命令来处理非平衡面板数据的问题,这两天我发现有同学还有一些别的交流群里的群友在用的时候就碰到这个问题,今天,我就打算细讲如何将非平衡面板转换成平衡面板。
首先,这个命令是 Stata 外部命令,需要先下载安装才能使用。下载安装的命令为: ssc install xtbalance
。完成后,输入 help xtbalance
查看帮助文档,以了解该命令的使用方法。
xtbalance
的语法格式: xtbalance, range(numlist) [ miss(varlist) ]
xtset panelvar timevar
或 tsset panelvar timevar
将数据设定成面板数据格式。接下来,你可以根据所需时间段来处理数据,比如我需要 1992-1998 年的平行面板,命令为 xtbalance, range(1992 1998)
。
timevar
不是 1991、1992、……2000 这样的连续时间,而是类似 1992、1994、1996 …… 2000 这种非连续时间的时,直接使用 xtbalance, range(1992 1998)
会导致所有观察值都被删除了。的结果将会删除你的整个样本,这是怎么回事呢?//数据生成
. set obs 100
. gen id = int(_n/5.001)+1
. bysort id:gen year = 1992 +2*(_n-1)
. xtset id year
panel variable: id (strongly balanced)
time variable: year, 1992 to 2000, but with gaps
delta: 1 unit
//取1992-1998年段的平衡面板
. xtbalance, range(1992 1998)
(20 observations deleted due to out of range)
(80 observations deleted due to discontinues)
即,该命令首先将不在你选定的时间段内的样本删掉,之后,它在清理每个 id 的时候,将组内非连续时间的 id 删掉,但为什么我的平衡面板会被全部删除呢?因为我的不是连续时间。那么连续是怎么计算的呢?我的猜测是这个命令按照连续时间来计算每个 id 的样本数量,将其样本数量与预计间隔相比较,即它在清理每个 id 的时候,将组内没有 1998 - 1992 + 1 数量的id删掉,但是我们的时间间隔不一样,每个组内的样本数是不一样的,我的每个 id 应该只有 ( 1998 - 1992 ) / 2 +1个,它按照连续时间来计算的话会比我多,所以它认为我的组内缺失了样本,不是平衡的,所以会将这些也删掉。结果,数据就全被删了。
我们这里就不贴xtbalance
命令的源代码,但是我通过自己编写的一个do文件来展示我猜测的具体操作流程。
我们首先生成一个 id
为 0 (1) 99,year
为 1991 (1) 2000 的平衡面板:
. clear
. set obs 1000
. gen id =int(_n/10.000001)
. bysort id :gen year = 1990 + _n
. xtset id year
panel variable: id (strongly balanced)
time variable: year, 1991 to 2000
delta: 1 unit
然后,我们生成均匀分布的随机数,将随机数小于 0.2 的样本删掉,即每条都有 20% 的概率被删掉,剩下的样本为非平衡的样本
. drop if runiform() <0.2
. xtset id year
panel variable: id (unbalanced)
time variable: year, 1991 to 2000, but with gaps
delta: 1 unit
同时,通过tab id
我们可以看每个id的样本数(受限于编辑器,这里只列出几行)都不一样
. tab id
id | Freq. Percent Cum.
------------+-----------------------------------
0 | 6 0.73 0.73
1 | 9 1.10 1.83
2 | 8 0.98 2.81
3 | 9 1.10 3.91
4 | 7 0.86 4.77
5 | 9 1.10 5.87
连享会计量方法专题……
实际上,xtbalance
命令的实现是这样的:
删除不在时间段内的样本;
计算每个id的样本数,如果每个 id 组内缺少样本,则将这个 id 的样本都删除。
假如,我们需要将上述数据 id : 0 (1) 99 year: 1991 (1) 2000的非平衡面板转为 id :0 (1) 99 year: 1992 (1) 1998的平衡面板的话,我们需要知道当转为平衡面板后,每个id相对应的只有1998-1992+1=7条记录
. preserve
. drop if year > 1998 | year < 1992
(243 observations deleted)
. bysort id :keep if _N ==7
(400 observations deleted)
. xtset id year
panel variable: id (strongly balanced)
time variable: year, 1992 to 1998
delta: 1 unit
. restore
. xtbalance, range(1992 1998)
(243 observations deleted due to out of range)
(400 observations deleted due to discontinues)
. xtset id year
panel variable: id (strongly balanced)
time variable: year, 1992 to 1998
delta: 1 unit
实际过程中,有许多数据库并不是连续时间的面板,这可能是因为多种原因,比如,某个数据库在调查数据时候,分别在 1990、1992、1994 每两年调查一次的,其实,这种满好的,因为有固定间隔,然而,当不是固定间隔的时候,处理数据的时候你可能需要多留意。
先生成平衡面板(不是连续时间)
*-生成非连续时间的平衡面板
. clear
. set obs 1000
. gen id =int(_n/10.000001)
. bysort id :gen year = 1990 + 2*_n -1
. xtset id year
panel variable: id (strongly balanced)
time variable: year, 1991 to 2009, but with gaps
delta: 1 unit
. xtset id year, delta(2)
panel variable: id (strongly balanced)
time variable: year, 1991 to 2009
delta: 2 units
. tab year
year | Freq. Percent Cum.
------------+-----------------------------------
1991 | 100 10.00 10.00
1993 | 100 10.00 20.00
1995 | 100 10.00 30.00
1997 | 100 10.00 40.00
1999 | 100 10.00 50.00
2001 | 100 10.00 60.00
2003 | 100 10.00 70.00
2005 | 100 10.00 80.00
2007 | 100 10.00 90.00
2009 | 100 10.00 100.00
------------+-----------------------------------
Total | 1,000 100.00
*-直接使用xtbalance的缺陷/
. preserve
. count
1,000
. xtbalance, range(1993 2005)
(300 observations deleted due to out of range)
(700 observations deleted due to discontinues)
. count
0
. restore
注意:
xtset id year
与 tsset id year
都可以同时设置面板xtset id year
命令会提示说你的数据 “strongly balanced" 但是时间有 "gap",如果你的面板 time variable
是有固定间隔的,那么你可以在 xtset id year, delta()
的 delta()
选项中设置。xtbalance
命令,我们可以看到,我们的非连续时间的平衡面板直接使用用xtbalance
是不合适的。再通过随机删除部分样本,使其成为非平衡面板:
. drop if runiform() <0.2
(168 observations deleted)
. xtset id year,delta(2)
panel variable: id (unbalanced)
time variable: year, 1991 to 2009, but with gaps
delta: 2 units
我们所需要的样本时间段为 1993(2)2005: 先查看一下数据:
. tab year
year | Freq. Percent Cum.
------------+-----------------------------------
1991 | 78 9.38 9.38
1993 | 84 10.10 19.47
1995 | 80 9.62 29.09
1997 | 82 9.86 38.94
1999 | 82 9.86 48.80
2001 | 88 10.58 59.38
2003 | 79 9.50 68.87
2005 | 86 10.34 79.21
2007 | 87 10.46 89.66
2009 | 86 10.34 100.00
------------+-----------------------------------
Total | 832 100.00
我们所需要的是 1993(2)2005 的时间段的话,每个 id 在 1993(2)2005时间段内的样本数应该是1+(2005-1993)/2 = 7,所以,我们的操作流程就是: 1.先只保留1993-2005年的所有样本,不在时间段内的删除掉; 2.计算每个id的样本数,只包括样本数为7的。
. preserve
. drop if year>2005 | year <1993
(251 observations deleted)
. bysort id :drop if _N != 7
(413 observations deleted)
. xtset id year,delta(2)
panel variable: id (strongly balanced)
time variable: year, 1993 to 2005
delta: 2 units
. restore
对于有固定间隔的平衡面板数据,我们可以预先生成一个新的时间变量 (连续的),进而使用 xtbalance
命令进行处理。
. xtset id year, delta(2)
panel variable: id (unbalanced)
time variable: year, 1991 to 2009, but with gaps
delta: 2 units
. bysort id: gen new_year = _n //使用该命令前一点要先对数据排序
* 或 gen new_year = 1 + (year - r(min))/2
现在 1993 年在 new_year 中就是 2,而 2005 年就是 8 ,然后用新的时间来设置面板,再使用xtbalance,range(2 8)
就OK了
. xtset id new_year
panel variable: id (unbalanced)
time variable: new_year, 1 to 10, but with gaps
delta: 1 unit
. xtbalance,range(2 8)
(251 observations deleted due to out of range)
(413 observations deleted due to discontinues)
. xtset id year,delta(2)
panel variable: id (strongly balanced)
time variable: year, 1993 to 2005
delta: 2 units
连享会计量方法专题……
股票日交易资料有一个典型的特征:所有公司的资料在非交易日都是缺失的。因此,虽然股票日交易资料本质上是一份连续数据,但 Stata 在接到 xtset id date
的通知后,将其视为非平衡面板数据。(Note: 这里暂不考虑那些在交易日里停牌的公司)
此时的处理方法与上一小节相似:可以先使用 bysort id: gen new_data=_n
命令或 egen new_date = group(date)
命令生成新的时间变量。
对于更为一般的情形,处理方法也会相对复杂:先删掉不在时间段内的样本,然后通过某种方法将你的时间变量转为一个新的具有连续时间的变量,之后通过每个 id 的样本数与为平衡时的样本数进行比较,一样则保留,否则删除。
在写作这篇推文过程中,我与吴雄多次沟通,受到了不少启发。
后续我们会将文中提及的 xtbalance
的局限一一解决掉,以便大家能够更为便捷地进行非平行面板 → 平行面板的转换。
计划添加的功能如下(欢迎各位补充,反馈至:arlionn@163.com ):
delta()
选项:以便处理有固定间隔的平衡面板数据;gen(newvarname)
选项:以便对平行面板构成的观察值进行标记;force
选项:由程序自动对用户的数据进行处理;上述想法促成了展金永等三位同学编写了 tobalance
命令,可以处理更为一般化的情形,详见 Stata新命令-tobalance:非平行面板转换为平行面板数据。
连享会-直播课 上线了!
http://lianxh.duanshu.com
免费公开课:
直击面板数据模型 - 连玉君,时长:1小时40分钟 Stata 33 讲 - 连玉君, 每讲 15 分钟. 部分直播课 课程资料下载 (PPT,dofiles等)
支持回看,所有课程可以随时购买观看。
专题 | 嘉宾 | 直播/回看视频 |
---|---|---|
⭐ 最新专题 ⭐ | DSGE, 因果推断, 空间计量等 | |
⭕ Stata数据清洗 | 游万海 | 直播, 2 小时,已上线 |
研究设计 | 连玉君 | 我的特斯拉-实证研究设计,-幻灯片- |
面板模型 | 连玉君 | 动态面板模型,-幻灯片- |
面板模型 | 连玉君 | 直击面板数据模型 [免费公开课,2小时] |
Note: 部分课程的资料,PPT 等可以前往 连享会-直播课 主页查看,下载。
关于我们
课程, 直播, 视频, 客服, 模型设定, 研究设计, stata, plus, 绘图, 编程, 面板, 论文重现, 可视化, RDD, DID, PSM, 合成控制法
等
连享会小程序:扫一扫,看推文,看视频……
扫码加入连享会微信群,提问交流更方便
✏ 连享会学习群-常见问题解答汇总:
✨ https://gitee.com/arlionn/WD