删除年份与条件筛选年份:TMT变动变量生成结果差异咨询
看起来你在尝试标识2006-2009年间高管团队(TMT)是否变动时,遇到了两段代码结果不一致的问题,咱们来拆解下原因,再给出靠谱的解决办法。
为什么两段代码结果有差异?
先明确你两段代码的核心逻辑差异:
第一段代码的逻辑
drop if Year > 2009 drop if Year < 2006 by id (id), sort: gen changed = (DirectorID[1] != DirectorID[_N])
这段代码先删除了2006-2009以外的所有观测,只保留目标区间的数据。但这里有个隐藏问题:by id (id), sort只是按id排序,没有按Year排序,所以每个id组内的第一个([1])和最后一个([_N])观测不一定对应2006年和2009年的记录——顺序是随机的,可能是任意年份的DirectorID被拿来比较。
第二段代码的逻辑
by id (id), sort: gen changed = (DirectorID[1] != DirectorID[_N]) if Year < 2010 & Year > 2005
这段代码保留了所有年份的数据,但同样没按Year排序。此时每个id组是该银行2005-2015年的全部观测,[1]大概率是2005年的记录,[_N]是2015年的记录,你实际在比较的是2005和2015年的DirectorID,完全偏离了“2006-2009年变动”的需求。而且changed变量只在2006-2009的观测上生成值,其余年份都是缺失值,这也和第一段代码的结果范围不同。
这两个逻辑偏差,就是导致247个案例结果不一致的核心原因。
正确的实现方法
你的需求是判断每个银行(id)2006年的TMT成员和2009年的是否存在变动,这里提供两种可靠的实现方式:
方法一:精准筛选目标年份后比较
这种方法先提取2006和2009年的数据,直接对比两年的DirectorID:
* 仅保留2006和2009年的观测 keep if Year == 2006 | Year == 2009 * 按id和Year排序,确保每个id下先出现2006年,再出现2009年 sort id Year * 对每个id,生成变动标识:2006和2009年的DirectorID是否不同 by id: gen changed = (DirectorID[1] != DirectorID[2]) if _N == 2 * 如果需要把这个变量匹配回原数据集(2005-2015全量数据),可以用临时文件合并 tempfile tmt_change save `tmt_change' use "your_original_dataset.dta", clear // 替换为你的原数据集路径 merge m:1 id using `tmt_change', keepusing(changed)
方法二:在全量数据中直接提取目标年份值对比
如果不想删除原数据,可以直接提取2006和2009年的DirectorID后比较:
* 先按id和Year排序,确保年份顺序正确 sort id Year * 提取每个id的2006年DirectorID by id: gen dir_2006 = DirectorID if Year == 2006 by id: egen dir_2006_final = max(dir_2006) // 确保每个id只保留一个2006年的值 * 提取每个id的2009年DirectorID by id: gen dir_2009 = DirectorID if Year == 2009 by id: egen dir_2009_final = max(dir_2009) * 生成变动标识变量 gen changed = (dir_2006_final != dir_2009_final) * 清理中间变量 drop dir_2006 dir_2006_final dir_2009 dir_2009_final
这两种方法都能精准对比2006和2009年的TMT成员,避免原代码中的排序和分组范围错误。
内容的提问来源于stack exchange,提问作者Alex Raaijmakers

