*! version 2.0.0 PS/PR 10Jun97. STB-41 sed9.1 *!! Based on Peter Sasieni's "running4.ado" emailed 09Jun97 program define running version 4.0 local varlist "req ex min(1) max(2)" local if "opt" local in "opt" local weight "aweight" #delimit ; local options "noGraph GEN(string) Knn(str) Double Repeat(int 1) Mean LOGit SPan(real 0) TItle(string) Symbol(str) Connect(str) PEn(str) CI GENSe(str) GENB(str) TWice *"; #delimit cr parse "`*'" local nv = (2-("`mean'"!=""))*(8+16)+9+12*("`weight'"!="")+8*(1-("`twice'"!="")) memchk byte `nv' if _rc==900 {exit} if "`gen'"!="" { confirm new var `gen' } if "`genb'"!="" { if "`twice'`mean'`logit'"!="" { di in red "genb not available with mean, twice or logit" exit 198 } confirm new var `genb' } if "`gense'"!="" { confirm new var `gense' if `repeat'>1 | "`double'`logit'`twice'"!="" { di in red "gense not available with repeat>1, twice or logit" exit 198 } } if "`ci'"!="" { if `repeat'>1 | "`double'`logit'`twice'"!="" { di in red "ci not available with repeat>1, twice or logit" exit 198 } } if `span'!=0 & "`knn'"!="" { di in red "cannot specify both span and knn" exit 198 } if `span'<0 | `span'>2-("`mean'"!="") { di in red "span must be between 0 and " 2-("`mean'"!="") exit 198 } if "`knn'"=="" { local knn 0 /* previous default */ } else { cap confirm var `knn' if _rc { confirm integer num `knn' } else { unabbrev `knn' local kvec $S_1 } } if "`double'"!="" { local repeat=2*`repeat' } local nrep `repeat' if `repeat'>7 { local repeat 7 noisily di in bl "[repeat set to 7]" } parse "`varlist'", parse(" ") local y `1' local x `2' tempvar Y X smooth sy rsy touse kr kl quietly { if "`weight'" != "" { tempvar sw w wt gen `w' `exp' replace `w'=. if `w'<=0 local exp "[`weight'=`w']" } mark `touse' `if' `in' markout `touse' `y' `x' `w' count if `touse' local cnt = _result(1) local IN "in 1/`cnt'" if `cnt'<5 { noisily error 2001 } if `span'!=0 { local knn=(`cnt'*`span'-1)/2 } else { if `knn'==0 {local knn = .5*`cnt'^0.8 } local span=(2*`knn'+1)/`cnt' } if "`kvec'" !="" { sum `kvec' if `touse' if _result(5)<1 | _result(1)!=`cnt' { nois di "knn-variable must be positive & non-missing" exit } local kk int(`kvec'/sqrt(`repeat') +.5) } else { local kk = int(`knn' /sqrt(`repeat') +.5) if `kk'<=0 { noi di in red "Span too small. Increase span or knn." exit 2002 } } if `knn'<=1 & "`ci'"!="" {nois di "[ci not produced when knn=1]"} sum `y' `exp' if `touse' local ycen=_result(3) gen `Y'=`y'-`ycen' if `touse' _crcslbl `Y' `y' if "`x'"!=""{ gen `X'=`x' if `touse' _crcslbl `X' `x' } else { gen `X'=_n if `touse' lab var `X' "n" } set graph off graph `y' `X' `exp' in 1/3, `options' set graph on sort `X' if "`weight'" != "" { gen double `sw'=. replace `w'=. if !`touse' sum `w' noi di in gr "(sum of wgt is " _result(1)*_result(3) ")" replace `w' = `w'/_result(3) gen `wt' = `w' local ks "(`sw'[_n+`kr']-cond(_n>`kl',`sw'[_n-`kl'],0))" local d3 "`sw'[_N]" local wX "`w'*" local wtX "`wt'*" local wn "`wt'`nk'*" local g_swby "by `X':replace `sw'=sum(`w') " local g_wt "by `X':replace `wt'=`sw'[_N]/_N " local gen_swt "replace `sw'=sum(`wt') `IN'" } else { local ks "(`kr'+`kl')" local d3 "_N" } gen `smooth'=`Y' lab var `smooth' "Smooth fit" gen double `sy'=sum(cond(_n<`cnt',(`X'==`X'[_n-1] |`X'==`X'[_n+1]), /* */ `X'==`X'[_n-1])) `IN' gen `rsy' = . local ties=`sy'[`cnt'] local xcen=(`X'[1]+`X'[`cnt'])/2 replace `X'=`X'-`xcen' `IN' sort `X' if `ties'>0 { tempvar Yt `g_swby' /* sw must be defined before d3 is used */ `g_wt' by `X':replace `sy'=sum(`wX'`Y') if `touse' by `X':replace `smooth'=`sy'[_N]/`d3' if `touse' if "`twice'"!=""{ gen `Yt'=`smooth' } } else { local Yt "`Y'" } `gen_swt' gen int `kl' = min(`kk'+1,_n) gen int `kr' = min(`kk',`cnt'-_n) if "`mean'"=="" { local mean "line" tempvar sxy rsxy beta rsx rsxx gen `beta'= . gen double `sxy'=sum(`wtX'`X') `IN' diff `rsx' `sxy' `kr' `kl' `ks' `cnt' gen replace `sxy'=sum(`wtX'((`X')^2)) `IN' diff `rsxx' `sxy' `kr' `kl' `ks' `cnt' gen gen `rsxy'=. } while `repeat'>0 { replace `sy'=sum(`wtX'`smooth') `IN' diff `rsy' `sy' `kr' `kl' `ks' `cnt' replace if "`mean'"=="line" { replace `sxy'=sum(`wtX'`X'*`smooth') `IN' diff `rsxy' `sxy' `kr' `kl' `ks' `cnt' replace replace `beta'=(`rsxy'-`rsx'*`rsy')/(`rsxx'-(`rsx')^2) `IN' replace `smooth'=cond((`rsxx'-`rsx'*`rsx') > max(0, /* */ `rsxx'/1e8), `rsy'+`beta'*(`X'-`rsx'), `rsy') `IN' } else { replace `smooth'=`rsy' `IN' } local repeat=`repeat'-1 } if "`twice'"!="" { tempvar res gen `res' = `Yt'-`smooth' local repeat `nrep' while `repeat'>0 { replace `sy'=sum(`wtX'`res') `IN' diff `rsy' `sy' `kr' `kl' `ks' `cnt' replace if "`mean'"=="line" { replace `sxy'=sum(`wtX'`X'*`res') `IN' diff `rsxy' `sxy' `kr' `kl' `ks' `cnt' replace replace `beta'=(`rsxy'-`rsx'*`rsy')/(`rsxx'-(`rsx')^2) `IN' replace `res'=cond((`rsxx'-`rsx'*`rsx') > max(0, /* */ `rsxx'/1e8), `rsy'+`beta'*(`X'-`rsx'), `rsy') `IN' } else { replace `res'=`rsy' `IN' } local repeat=`repeat'-1 } replace `smooth'=`smooth'+`res' `IN' } if `ties'>0 { by `X':replace `sy'=sum(`smooth') if `touse' by `X':replace `smooth'=`sy'[_N]/_N if `touse' } if "`ci'"!="" | "`gense'"!="" { drop `sy' `rsy' tempvar se sigma2 gen double `se'=(`Y'-`smooth')^2 if `ties'>0 { `g_swby' by `X':replace `se'=sum(`wX'`se') if `touse' by `X':replace `se'=`se'[_N]/`d3' if `touse' } `gen_swt' replace `se'=sum(`wtX'`se') `IN' * Adjustment for estimating parameters made in se not sigma2 * diff `sigma2' `se' `kr' `kl' `ks' `cnt' gen if "`mean'"=="line" { replace `se'=sqrt(`sigma2'* /* */ cond((`rsxx'-`rsx'*`rsx') > max(0,`rsxx'/1e8), /* */ ((`kl'+`kr')/(`kl'+`kr'-2)) /* */ *(1+(`X'-`rsx')^2/(`rsxx'-(`rsx')^2))/`ks' , /* */ 1/(`kl'+`kr'-1) )) `IN' } else { replace `se'=sqrt(`sigma2'/(`kl'+`kr'-1)) `IN' } drop `sigma2' if `ties'>0 { `g_swby' by `X':replace `se'=sum((`se')^2) if `touse' by `X':replace `se'=sqrt(`se'[_N]/_N) if `touse' } } replace `X'=`X'+`xcen' `IN' replace `Y'=`Y'+`ycen' `IN' replace `smooth'=`smooth'+`ycen' `IN' if "`mean'"=="mean" &" `kvec'"=="" { local k2=`cnt'+1-`kk' replace `smooth'=. in 1/`kk' replace `smooth'=. in `k2'/l } if "`logit'"!="" { sum `y' if `touse' if _result(5)<-5e-9 | _result(6)>1+5e-9 { noi di "[Yvar out of range [0,1]. logit not available]" } else { sum `y' if `y'>0 & `y'<1 &`touse' local aL = min(1/(min(`span',1)*`cnt'+1),_result(5)) local aU = max(1-1/(min(`span',1)*`cnt'+1),_result(6)) replace `smooth'=log(cond(`smooth'< `aL', `aL'/(1-`aL'), /* */ cond(`smooth'>`aU',`aU'/(1-`aU'),`smooth'/(1-`smooth')) /* */ )) if `smooth' !=. `IN' local laL = log(`aL'/(1-`aL')) local laU = log(`aU'/(1-`aU')) local adj=(`laU'-`laL')/25 replace `Y'=cond(`y'<`aL', `laL'-(1.3+uniform())*`adj', /* */ cond(`y'>`aU', `laU'+(1.3+uniform())*`adj', /* */ log(`y'/(1-`y')) )) `IN' } } * GRAPH (If required) if "`graph'"!="nograph" { if "`ci'"!="" { local df=`kl'+`kr'-("`mean'"=="line") local t=invt(`df',${S_level}/100) tempvar l u gen `l'=`smooth'-`t'*`se' gen `u'=`smooth'+`t'*`se' local pp "44" } if "`title'" ==""{ local title "Running `mean' smoother" } if "`symbol'" ==""{ if `cnt'<300 { local symbol o } else { local symbol . } } local symbol "`symbol'iii" if "`connect'"==""{ local connect ".lll" } if "`pen'" ==""{ local pen "23`pp'" } drop `kl' `kr' `touse' noisily graph `Y' `smooth' `l' `u' `X' `exp', `options' /* */ ti(`title') s(`symbol') c(`connect') pen(`pen') } if "`gen'`genk'`gense'" !="" {drop `Y' `X'} if "`gen'" !="" {rename `smooth' `gen'} if "`gense'"!="" {rename `se' `gense'} if "`genb'" !="" {rename `beta' `genb'} } global S_1 `knn' global S_2 `span' end prog def diff local new `1' local old `2' local kr `3' local kl `4' local ks `5' local cnt `6' local com `7' `com' `new' =(`old'[_n+`kr'] - cond(_n>`kl',`old'[_n-`kl'],0))/`ks' /* */ in 1/`cnt' end *! version 1.0 17 Jun 1997 program define memchk version 5.0 quietly describe, detail short local width = _result(3) local ws = _result(6) while "`1'"!="" { if "`2'"=="" { error 198 } confirm integer number `2' if "`1'"=="int" { local width = `width' + 2*`2' } else if "`1'"=="byte" { local width = `width' + `2' } else if "`1'"=="long" | "`1'"=="float" { local width = `width' + 4*`2' } else if "`1'"=="double" { local width = `width' + 8*`2' } else if substr("`1'",1,3)=="str" { local len = substr("`1'",4,.) confirm integer number `len' local width = `width' + `len'*`2' } else { error 198 } mac shift 2 } if `width' > `ws' { di _col(8) in red "insufficient memory" exit 900 } end