如何使用Stata局部宏按资产规模阈值拆分数据集
代码问题诊断
- 核心错误是局部宏名拼写不一致:定义宏时用的名称是
subset,循环调用时写为`subsets',多了末尾的s,导致循环无匹配项直接跳过,完全不会执行内部逻辑。 - 缺少拆分结果的持久化逻辑:
preserve之后既没有restore回滚,也没有将拆分好的子集存为本地文件,循环跑完后仍会回到原始数据集,看不到任何拆分结果。 - 阈值定义存在不一致风险:需求描述的阈值是10/100,代码里硬编码的是10000000/100000000,需要注意单位统一,避免逻辑与需求不符。
- 存在冗余重复代码:三个分支的逻辑高度重合,重复编写容易出现笔误。
修复后可运行代码
简化优化版(推荐)
避免重复分支逻辑,可灵活调整阈值和命名:
* 三个区间的标识,对应需求里的<10、10-100、>100 local subset_labels 10 55 100 * 对应三个区间的阈值上下限,单位和你原有代码保持一致,可根据实际单位调整 * 格式为:区间1下限 区间1上限 | 区间2下限 区间2上限 | 区间3下限 区间3上限,.表示无穷大 local thresholds "0 10000000 | 10000000 100000000 | 100000000 ." foreach lab of local subset_labels { preserve * 提取当前区间的上下限 gettoken thres thresholds: thresholds, parse("|") gettoken low high: thres * 标记符合区间要求的观测 gen in_range = (assets > `low' & assets <= `high') if !missing(assets) * 按公司维度筛选:只要公司有一期符合区间要求,就保留该公司所有观测 bysort company_id: egen keep_company = max(in_range) keep if keep_company == 1 * 保存子集到当前工作目录,文件名带区间标识 save "assets_subset_`lab'.dta", replace restore }
如果不需要保留公司全周期数据,只留存符合资产阈值的单条观测,删除bysort company_id...那行,直接写keep if in_range == 1即可。
原有分支写法修复版
如果你偏好原来的分支写法,仅修正核心错误即可运行:
* 宏名统一为subset,定义和调用保持一致 local subset 10 55 100 foreach subset in `subset' { preserve if `subset' == 100 { gen subset_obs = (assets >= 100000000) bysort company_id : egen subset_id = max(subset_obs) keep if subset_id == 1 * 保存子集 save "assets_gt100.dta", replace } else if `subset' == 10 { gen subset_obs = (assets <= 10000000) bysort company_id : egen subset_id = max(subset_obs) keep if subset_id == 1 save "assets_le10.dta", replace } else if `subset' == 55 { gen subset_obs = (assets > 10000000 & assets < 100000000) bysort company_id : egen subset_id = max(subset_obs) keep if subset_id == 1 save "assets_between10_100.dta", replace } restore }
内容的提问来源于stack exchange,提问作者gobygoul
相关产品推荐
相关产品推荐

