Stata | 用 frames 来“分蛋糕”

提出问题

故事还要从这张滑稽的 Excel 表格说起,如果我有一批蛋糕,要公平的分给张三、李四和王五。而且我的蛋糕还可能很多,多到复制粘贴会下拉到眼花;朋友也不止他仨,还会有更多的朋友。该咋做?
换句话说,问题其实是:如何将 1 列数据平均拆分成 n 列?
思路分析
想了想,可能最直观的解决方法是使用
perserve
和
restroe
先拆分为 n 份子文件,再将数据合并。但这涉及数据导进导出,比较麻烦。尝试使用 Stata 16.0 的 Data Frames 功能解决,对比二者谁更优雅。
实现过程
生成数据
演示需要,生成包含
x
变量,200 个观测值的数据。其中,暂元
group
表示需要分成的列数。演示需要,下方设置为分为 3 组。
version 16.0
clear
set obs 200
set seed 2020
gen x = 10*runiform()
使用 preserve 和 restore
local group = 3 // 分成 3 组
* 组别识别变量
gen n = _n
gen temp = int(autocode(n,`group',0,_N))
* 拆分成子集
levelsof temp
local a = 1
foreach i in `r(levels)'{
preserve
gen x`a' = x if temp == `i'
drop if x`a' == .
gen temp2 = _n
keep temp2 x`a'
save "temp_x_`a'.dta", replace
local a = `a' + 1
restore
* 合并子集
use "temp_x_1.dta", clear
forvalues i = 2/`group'{
qui merge 1:1 temp2 using "temp_x_`i'.dta", nogen
drop temp*
save "result.dta", replace
* 清除临时文件
fs "temp_x*.dta"
foreach i in `r(files)'{
erase `i'
细节:先采用
autocode()
函数自动进行分组,然后使用
keep...if...
分别保存为
x1
、
x2
和
x3
三份数据,最后再匹配成 3 列数据。最后的结果如下:

使用 Data Frames
frame reset
set obs 200
set seed 2020
gen x = 10*runiform()
local g = 3
gen n = _n
gen temp = int(autocode(n,`g',0,_N))
local a = 1
levelsof temp
foreach i in `r(levels)'{
cap frame drop group`a'
frame copy default group`a'
frame change group`a'
keep if temp == `i'
gen x`a' = x
gen temp2 = _n
keep x`a' temp2
local a = `a' + 1
frame change default
frame copy default result
gen temp2 = _n
keep temp2
forvalues i = 1/`g'{
frlink 1:1 temp2, frame(group`i')