我有一个面板数据集,用于每年大约 10,000 人的多个波次 (13),人们在不同的时间点进出。我对人们随着时间的推移被诊断出患有疾病时会发生什么感兴趣。因此,我需要重新编码时间变量,使其在诊断时t=0
第一波,然后t=1
是明年,依此类推,以便我所有的个体都是可比的(我想-1
t-1
等)。但是我不确定如何在stata
中做到这一点。有人能提供建议吗?非常感谢
每人一次诊断的情况
clear all
set more off
*----- example data -----
set obs 100
set seed 2357
generate id = _n
generate year = floor(10 * runiform()) + 1990
expand 5
bysort id: replace year = year + _n
bysort id (year): generate diag = cond(_n == 3, 1, 0)
list in 1/20, sepby(id)
*----- what you seek -----
bysort id (diag): gen time = year - year[_N]
sort id year
list in 1/20
我假设与@RichardHerron相同的数据结构并使用他的例子。 diag
是一个指示变量,在诊断时取值为 1,否则取值为 0(每人仅考虑一个诊断)。
bysort
完成的排序至关重要。保存诊断时间的观察结果被推到数据库的末尾(由id
组),然后剩下要做的就是将所有year
与该参考年进行比较(减去)。有关系统变量(如 _N
)的详细信息,请参阅help _variables
。
每人多次诊断的情况
如果每人进行多次诊断,但我们只关心第一次出现(根据year
),我们可以做到:
gsort id diag -year
by id: gen time = year - year[_N]
简单但不是最佳解决方案
假设诊断时diagnosis
为 1(每人最多一次),否则为 0。那么诊断时间是最简单的
egen time_diagnosis = total(diagnosis * year), by(id)
但是您需要忽略任何零。为了说明这一点,
replace time_diagnosis = . if time_diagnosis == 0
更好的选择
如果发生多种诊断,则更复杂但更可取的替代方法可以处理它们:
egen time_diagnosis = min(year / diagnosis), by(id)
因为当diagnosis
为 1 时year / diagnosis
year
,否则缺少。如果没有诊断,这将产生缺失值,这是应该的。
然后减去它以获得一个新的时间变量。
gen time2 = time - time_diagnosis
简而言之,我认为您可以通过两个语句来完成此操作,也可以处理面板结构。
更新
@Richard赫伦问为什么egen
与by()
一起使用,而不仅仅是
gen time_diagnosis = time * diagnosis
这样做的一个限制是,"正确"值只包含在diagnosis
为 1 的观测值中;该值仍然必须"分散"到同一id
的其他值。但这正是egen
在这里所做的。在最简单的情况下,一个诊断time * diagnosis
的总和只是time * 1
或time
,因为任何零对总和都没有影响。
提供测试数据通常很有帮助,但在这里它们很容易生成。诀窍是找到每个人的第一年(我的fyear
),我将用egen
min()
来做。然后,我将从实际年份中减去第一年fyear
,以找到与诊断ryear
相关的年份。
/* generate panel */
clear
set obs 10000
generate id = _n
generate year = floor(10 * runiform()) + 1990
expand 10
bysort id: replace year = year + _n
sort id year
list in 1/20
/* generate relative year */
bysort id: egen fyear = min(year)
generate ryear = year - fyear
list in 1/20
如果小组中的第一年不是诊断,那么只需根据诊断标准构建fyear
。
编辑:更多地考虑这一点,也许这是您遇到困难的最后一部分(即,确定诊断年份以从日历年中减去)。这就是我要做的。
bysort id (year): generate diagnosis = cond(_n == 5, 1, 0)
preserve
tempfile diagnosis
keep if (diagnosis == 1)
rename year dyear
keep id dyear
save `diagnosis'
restore
merge m:1 id using `diagnosis', nogenerate
generate ryear2 = year - dyear