📄 st_set.ado
字号:
*! version 6.0.12 11jul2002
program define st_set
version 6, missing
* di `"`0'"'
/* { */
if "`1'"=="clear" {
Clear
exit
}
if "`1'" != "set" { exit 198 }
#delimit ;
args
cmd
stopts /* "" or "notable" */
id /* id: <varname> | <nothing> */
bt /* base time: <varname> */
bt0 /* enter time: <exp> | <nothing> */
failure /* failure varname[=[=]numlist) | <nothing> */
bs /* scale: <#> */
enter /* 1st enter: "t[ime] <exp>" |
"e[vent] <numlist>" |
<nothing> */
exit /* last exit: "t[ime] <exp>" |
"e[vent] <numlist>" |
<nothing> | */
origin /* origin: "t[ime] <exp>" |
"e[vent] <numlist>" |
<nothing> */
ifexp /* if exp: <exp> | <nothing> */
if /* if(): <exp> | <nothing> */
ever /* ever(): <exp> | <nothing> */
never /* never(): <exp> | <nothing> */
after /* after(): <exp> | <nothing> */
before /* before(): <exp> | <nothing> */
wt /* wgt type: <wgttype> */
wv /* wgt var: <varname> | <#> */
show /* show: "show" |
"noshow" |
<nothing> */
full /* marker: <nothing> | "past" |
"future" | "past future" */
;
#delimit cr
if "`full'"!="" {
/* save everything possibly relevant */
local fenter `"`enter'"'
local fexit `"`exit'"'
local forig `"`origin'"'
local fif `"`if'"'
local fever `"`ever'"'
local fbefor `"`before'"'
local fafter `"`after'"'
/* now fill in what is appropriate */
tempvar ever
qui gen byte `ever' = _st
local if
if "`full'"=="past future" | "`full'"=="past" {
local origin "min"
local enter
local after
}
if "`full'"=="past future" | "`full'"=="future" {
local exit "time ."
local before
}
}
/*
di `"cmd |`cmd'|"'
di `"stopts |`stopts'|"'
di `"id |`id'|"'
di `"bt |`bt'|"'
di `"bt0 |`bt0'|"'
di `"failure |`failure'|"'
di `"bs |`bs'|"'
di `"enter |`enter'|"'
di `"exit |`exit'|"'
di `"origin |`origin'|"'
di `"ifexp |`ifexp'|"'
di `"if |`if'|"'
di `"ever |`ever'|"'
di `"never |`never'|"'
di `"after |`after'|"'
di `"before |`before'|"'
di `"wt |`wt'|"'
di `"wv |`wv'|"'
di `"show |`show'|"'
*/
/* edit options */
if `"`bt0'"'=="." { local bt0 }
if `"`enter'"'=="." { local enter }
if `"`exit'"'=="." { local exit }
if `"`origin'"'=="." { local origin }
if `"`scale'"'=="." { local scale 1 }
if `"`if'"'=="." { local if }
if `"`if'"'=="1" { local if }
if `"`ever'"'=="." { local ever }
if `"`ever'"'=="1" { local ever }
if `"`never'"'=="." { local never }
if `"`never'"'=="0" { local never }
if `"`before'"'=="." { local before }
if `"`ifexp'"'=="." { local ifexp }
if `"`ifexp'"'=="1" { local ifexp }
/* end edit options */
if "`id'"!="" {
if `"`failure'"'=="" {
di in red /*
*/ "specifying option id() requires you also specify option failure()"
exit 198
}
}
if "`bt0'" != "" {
unab bt0: `bt0', max(1) name(time0())
}
if (`"`failure'"'!="1" & `"`failure'"'!=".") | `"`id'"'!="" {
Failure `failure'
local bd `s(bd)'
local event `s(event)'
}
/* interpret enter(), exit(), origin() */
Iop "`id'" "enter" `"`enter'"'
if `"`s(texp)'"' != "0" {
local en_exp `s(texp)'
}
local en_ivar `s(ivar)'
local en_list `s(ilist)'
if `"`exit'"'!="failure" {
Iop "`id'" "exit" `"`exit'"'
local ex_exp `s(texp)'
local ex_ivar `s(ivar)'
local ex_list `s(ilist)'
}
if `"`origin'"'!="min" {
Iop "`id'" "origin" `"`origin'"'
if `"`s(texp)'"' != "0" {
local or_exp `s(texp)'
}
local or_ivar `s(ivar)'
local or_list `s(ilist)'
}
else local or_cl "min"
/* clear weight if weight=1 */
if `"`wv'"'=="1" {
local wt
local wv
}
else if "`wv'"!="" {
unab wv: `wv', max(1)
}
quietly {
/*
Step 1. apply restrictions before we
interpret base time
*/
if `"`ifexp'"' != "" {
local ifif `"if `ifexp'"'
}
if "`wt'" != "" {
tempvar goodwgt
mark `goodwgt' `ifif' [`wt'=`wv']
}
tempvar touse
mark `touse' `ifif'
local ifif
count if `touse'==0
local L_ifexp = r(N)
local L_id 0
if "`id'"!="" {
count if missing(`id') & `touse'
local L_id = r(N)
replace `touse' = 0 if missing(`id')
}
count if `bt'>=. & `touse'
local L_bt = r(N)
replace `touse' = 0 if `bt'>=.
if "`wt'"!="" & "`id'"!="" {
sort `touse' `id' `bt'
capture by `touse' `id': /*
*/ assert `wv'==`wv'[1] if `touse'
if _rc {
di in red "weight not constant within `id'"
exit 459
}
}
/*
Step 2. Construct d
*/
tempvar d
if `"`event'"'!="" {
gen byte `d' = 0 if `touse'
tokenize `event'
while "`1'"!="" {
replace `d' = 1 if `bd'==`1' & `touse'
mac shift
}
}
else {
if "`bd'"!="" {
gen byte `d' = (`bd'!=0 & `bd'<.) if `touse'
}
else gen byte `d' = 1 if `touse'
}
/*
Step 3. construct origin
*/
if "`or_cl'"=="" {
if `"`or_exp'"'!="" | `"`or_ivar'"'!="" {
tempvar zero
if `"`or_exp'"' != "" {
tempvar z1
Smallest `z1' `"`or_exp'"' `touse' "`id'" `bt'
}
if "`or_ivar'" != "" {
tempvar z2
FirstEv `z2' /*
*/ `"`or_list'"' `touse' "`id'" `bt' `or_ivar'
}
Choose `zero' max "`z1'" "`z2'" `touse'
compress `zero'
}
else local zero 0
}
else {
tempvar zero
if `"`bt0'"'!="" {
summarize `bt0' if `touse'
gen double `zero' = r(min) if `touse'
}
else {
summarize `bt' if `touse'
gen double `zero' = r(min)-1 if `touse'
}
compress `zero'
}
/* note, `zero'<0 | `zero'>=. are possible at this point */
/*
Step 4. Make t
*/
tempvar t
gen double `t' = (`bt'-`zero')/`bs' if `touse'
compress `t'
/* note: `t' < 0 | `t'>=. are possible at this point */
/*
Step 5. make t0
make 2nd touse, touse2, update it for
t0() problems
*/
tempvar t0 touse2
gen byte `touse2' = `touse'
local L_ut0m 0
local L_ut0t 0
local L_order 0
local L_ord2 0
if "`bt0'"!="" {
count if (`bt0')>=. & `touse2'
local L_ut0m = r(N)
replace `touse2' = 0 if (`bt0')>=.
count if (`bt0')>=`bt' & `touse2'
local L_ut0t = r(N)
replace `touse2' = 0 if (`bt0')>=`bt'
gen double `t0' = ((`bt0')-`zero')/`bs' if `touse2'
if "`id'"!="" {
tempvar bad
sort `touse2' `id' `bt'
by `touse2' `id': gen byte `bad' = /*
*/ (`bt'[_n-1]>`bt0' & _n>1) | /*
*/ `bt0'>`bt'[_n+1] /*
*/ if `touse2'
count if `bad'==1
local L_ord2 = r(N)
replace `touse2'=0 if `bad'==1
drop `bad'
}
}
else {
if "`id'"!="" {
sort `touse2' `id' `bt'
tempvar bad
by `touse2' `id': gen byte `bad' = /*
*/ `bt'==`bt'[_n-1] | `bt'==`bt'[_n+1] /*
*/ if `touse2'
count if `bad'==1
local L_order = r(N)
by `touse2' `id': gen double `t0' = /*
*/ cond(_n==1, /*
*/ cond(`t'[2]<=0, 2*`t'[1], 0), /*
*/ `t'[_n-1]) if `touse2'
replace `touse2' = 0 if `bad'==1
replace `t0' = . if `bad'==1
drop `bad'
}
else gen double `t0' = 0 if `touse2'
}
/* note: `t0' < 0 | `t0'>=. are possible at this point */
/*
Step 6. make first enter time
going to use obs touse, not touse2,
but do not double count
*/
if `"`en_ivar'"'!="" | `"`en_exp'"'!="" {
tempvar t_en
if `"`en_exp'"'!="" {
tempvar t1
Smallest `t1' `"`en_exp'"' `touse' "`id'" `bt'
}
if `"`en_ivar'"'!="" {
tempvar t2
FirstEv `t2' /*
*/ `"`en_list'"' `touse' "`id'" `bt' `en_ivar'
}
Choose `t_en' max "`t1'" "`t2'" `touse'
replace `t_en' = (`t_en'-`zero')/`bs'
compress `t_en'
}
else local t_en 0
/*
Step 7. make last exit time
use touse rather than touse2, but
do not double count
*/
if `"`ex_ivar'"'!="" | `"`ex_exp'"'!="" {
tempvar t_ex
if `"`ex_exp'"'!="" {
tempvar tex1
Smallest `tex1' /*
*/ `"`ex_exp'"' `touse' "`id'" `bt'
}
if `"`ex_ivar'"'!="" {
tempvar tex2
FirstEv `tex2' /*
*/ `"`ex_list'"' `touse' "`id'" `bt' `ex_ivar'
}
Choose `t_ex' min "`tex1'" "`tex2'" `touse'
replace `t_ex' = (`t_ex'-`zero')/`bs'
compress `t_ex'
}
else {
if "`id'"!="" {
/* use first failure event */
tempvar t_ex
FirstEv `t_ex' "1" `touse' "`id'" `bt' `d'
replace `t_ex' = (`t_ex'-`zero')/`bs'
compress `t_ex'
}
else local t_ex .
}
/* bring touse and touse2 back together */
replace `touse' = 0 if `touse2'==0
drop `touse2'
/*
Step 8. apply other restrictions.
Performed in bt space because t might
have missing values
*/
tempvar alsorm wrk
gen byte `alsorm' = 0
if `"`if'"'!="" {
replace `alsorm'=1 if (`if')==0
}
if `"`ever'"'!="" {
HasId ever `id'
sort `touse' `id' `bt'
by `touse' `id': gen float `wrk'=/*
*/ sum(cond(`ever',1,0)) if `touse'
by `touse' `id': replace `alsorm'=1 if `wrk'[_N]==0
drop `wrk'
}
if `"`never'"' != "" {
HasId never `id'
sort `touse' `id' `bt'
by `touse' `id': gen float `wrk'=/*
*/ sum(cond(`never',1,0)) if `touse'
by `touse' `id': replace `alsorm'=1 if `wrk'[_N]
drop `wrk'
}
if `"`after'"' != "" {
HasId after `id'
sort `touse' `id' `bt'
by `touse' `id': gen float `wrk' = /*
*/ sum(cond(`after',1,0)) if `touse'
by `touse' `id': replace `alsorm'=1 if `wrk'==0
drop `wrk'
}
if `"`before'"' != "" {
HasId before `id'
sort `touse' `id' `bt'
by `touse' `id': gen float `wrk' = /*
*/ sum(cond(`before',1,0)) if `touse'
by `touse' `id': replace `alsorm'=1 if `wrk'
drop `wrk'
}
count if `alsorm' & `touse'
local L_res = r(N)
replace `touse'=0 if `alsorm'
drop `alsorm'
/*
Step 9. apply restrictions due to
enter and exit times
*/
/* cannot enter sample until variable enter.
Ergo, enter<0 or enter>=. are okay.
if t0=5 and enter<0 or enter>=., they still enter at 5
*/
/* records that have no entry time are excluded */
count if (`t_en'>=. | `zero'>=.) & `touse'
local L_never = r(N)
replace `touse'=0 if `t_en'>=. | `zero'>=.
/* records that end prior to enter time are excluded */
count if `t'<=`t_en' & `t_en'<. & `touse'
local L_prior = r(N)
replace `touse'=0 if `t'<=`t_en' & `t_en'<.
/* records that begin before enter and end after need
resetting
*/
replace `t0' = `t_en' if `t0'<=`t_en' & `t'>`t_en' & `touse'
/* exit times: missings just mean infinity */
count if `t0'>=`t_ex' & `touse'
local L_after = r(N)
replace `touse'=0 if `t0'>=`t_ex'
replace `d' = 0 if `t0'<`t_ex' & `t'>`t_ex'
replace `t' = `t_ex' if `t0'<`t_ex' & `t'>`t_ex'
replace `t0' = 0 if `t0'<0 & `touse'
/*
Step 10. apply implied restrictions
*/
count if `t0' >= `t' & `touse'
local L_t0t = r(N)
replace `touse'=0 if `t0'>=`t'
/*
count if `t0'<0 & `touse'
local L_neg = r(N)
replace `touse' = 0 if `t0'<0 | `t'<0
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -