我正在使用carryforward
(ssc install carryforward
)填写缺失的观察结果。我的一些数据是年度数据,我希望将它们用于随后的月度观察,但前提是数据不到两年。我可以使用dynamic_condition()
选项实现此逻辑,尤其是使用@
吗?我必须为许多变量完成此操作,并且希望避免大量变量生成和丢弃(并且我真的想知道它是否可能)。
以下"手册"解决方案有效,但是我可以使用dynamic_condition()
动态复制吗?我的尝试失败了。
/* generate data with observation every June */
clear
set obs 100
generate date_ym = ym(2001, 1) + (_n - 1)
format date_ym %tm
generate date_m = month(dofm(date_ym))
generate x = runiform() if (date_m == 6) & !inlist(_n, 30, 42)
/* carryforward (ssc install carryforward), "manual" solution */
egen date_m2 = group(date_ym) if !missing(x)
carryforward date_m2, replace
bysort date_m2 (date_ym): generate date_m3 = cond(_n > 24, ., date_m2)
carryforward x if !missing(date_m3), gen(x_cf)
tsset date_ym
list, sep(12)
/* can I replicate this with dynamic_condition() option? */
/* no time series operators with @ */
/* carryforward x, gen(x_cf2) dynamic_condition(sum(d.@ == 0) < 24) */
/* x_cf2: d.x_cf2 invalid name */
/* second @ doesn't work */
/* carryforward x, gen(x_cf3) dynamic_condition(sum(@ == @[_n - 1]) < 24) */
/* x_cf3: equation [_n-1] not found */
答案 0 :(得分:2)
披露:我不会使用carryforward
(SSC),但这是因为我倾向于按照我理解的原则回顾原则,正如记录here。 / p>
为此,您需要不仅记录先前的非缺失值,还记录变量最后一次不丢失的日期。之前出现了这种情况:请参阅this answer
更简单方法的本质是:
clear
set seed 2803
set obs 100
generate date_ym = ym(2001, 1) + (_n - 1)
format date_ym %tm
generate x = runiform() if inlist(_n, 30, 42)
gen last = date_ym if !missing(x)
replace last = last[_n-1] if missing(last)
replace x = x[_n-1] if missing(x) & (date_ym - last) < 24
对面板的推广使用by:
,对多个变量的泛化使用foreach
循环。如果缺失值的日期对于不同的变量可能不同,那么这大多只是改变循环。
原则上,假设我们在仲裁varlist上循环并且缺失值的日期不同,但我们使用在24个月内使用最后一个值的规则。
gen last = .
quietly foreach v of varlist <varlist> {
replace last = cond(!missing(`v'), date_ym, .)
replace last = last[_n-1] if missing(last)
replace `v' = `v'[_n-1] if missing(`v') & (date_ym - last) < 24
}