*! 2.0.0 17 May 2005 (SJ 5-3: sg149_1; STB-56: sg149) /* tests for seasonality with a variable population at risk follows the tests given in Walter & Elwood (1975), Edwards (1961): default is Walter & Elwood test using equal month lengths when a population variable is specified and Edwards test otherwise */ program seast, rclass version 8 syntax varlist(min=1 max=2) /// [ , EXact NOTab Generate(string) SECtor(varname) LENgth(varname) ] if "`sector'" == "" { capture confirm variable month if _rc { di as err "default month variable not found" exit 498 } local sector "month" } summ `sector', meanonly local k = r(max) if "`exact'" != "" & "`length'" == "" & `k' != 12 { di as err "can only use exact with monthly data or length()" exit 198 } if "`generate'" != "" confirm new var `generate' tokenize `varlist' args obs pop if "`pop'" == "" { local edwards 1 tempvar pop gen byte `pop' = 1 } else local edwards 0 tempvar theta work days x exp quietly { summ `pop', meanonly local M = r(sum) summ `obs', meanonly local N = r(sum) if "`length'" != "" { summ `length', meanonly gen `x' = 2 * _pi / r(sum) * `length' gen `theta' = _pi / `k' local stheta = _pi / `k' forval i = 2 / `k' { summ `x' if `sector' == `i' - 1, meanonly replace `theta' = /// `stheta' + r(max) if `sector' == `i' local stheta = `stheta' + r(max) } } else { if "`exact'" == "" { gen `theta' = _pi / `k' * ((2 * `sector') - 1) } else { // `k' == 12 local exacttxt " (using exact month lengths)" gen `days' = 31 if inlist(`sector',1,3,5,7,8,10,12) replace `days' = 28.25 if `sector' == 2 replace `days' = 30 if `days' == . gen `x' = 2 * _pi / 365.25 * `days' gen `theta' = _pi / 12 local stheta = _pi / 12 forval i = 2 / 12 { summ `x' if `sector' == `i' - 1, meanonly replace `theta' = `stheta' + r(max) if `sector' == `i' local stheta = `stheta' + r(max) } } } gen `work' = sum(sqrt(`obs')) local W = `work'[_N] // Calculate observed centre point replace `work' = sum((sqrt(`obs')) * (cos(`theta'))) local xbar = `work'[_N] / `W' replace `work' = sum((sqrt(`obs')) * (sin(`theta'))) local ybar = `work'[_N] / `W' // Getting expected centre point if !`edwards' { replace `work' = sum(sqrt(`pop')) local srmi = `work'[_N] replace `work' = sum(sqrt(`pop') * cos(`theta')) local xhat = `work'[_N] / `srmi' replace `work' = sum(sqrt(`pop') * sin(`theta')) local yhat = `work'[_N] / `srmi' } else { local xhat = 0 local yhat = 0 } // Variances replace `work' = 0.25 * cos(`theta') * cos(`theta') sum `work', meanonly local vx1 = r(sum) replace `work' = 0.25 * sin(`theta') * sin(`theta') summ `work', meanonly local vy1 = r(sum) if !`edwards' { replace `work' = sqrt(`N' * `pop' / `M') summ `work', meanonly local v2 = r(sum) * r(sum) local varx = `vx1' / `v2' local vary = `vy1' / `v2' } local alpha = 4 * sqrt((`xbar' - `xhat')^2 + (`ybar' - `yhat')^2) local thstar = atan((`ybar' - `yhat') / (`xbar' - `xhat')) if `xbar' - `xhat' < 0 local thstar = _pi + `thstar' if `edwards' { replace `work' = (1 + `alpha' * cos(`theta' - `thstar')) summ `work', meanonly gen `exp' = `N' * `work' / r(sum) local test = 0.5 * `alpha' * `alpha' * `N' } else { replace `work' = `pop' * (1 + `alpha' * cos(`theta' - `thstar')) summ `work', meanonly gen `exp' = `N' * `work' / r(sum) local test = /// (((`xbar' - `xhat') / sqrt(`varx'))^2) + (((`ybar' - `yhat') / sqrt(`vary'))^2) } replace `work' = ((`obs' - `exp')^2)/`exp' summ `work', meanonly local fit = r(sum) local thstar = `thstar' * 180 / _pi local foy = cond(`thstar' < 0, 1 + `thstar'/360, `thstar'/360) } // end quietly if "`notab'" == "" { di _n as txt "{hline 14}{c TT}{hline 23}" local which = cond(`k' == 12, "Month", "Sector") di as txt "`which'" "{col 15}{c |} Observed" "{col 31}Expected" di as txt "{hline 14}{c +}{hline 23}" tokenize "`c(Months)'" forval i = 1 / `k' { summ `obs' if `sector' == `i', meanonly local obsi = r(max) summ `exp' if `sector' == `i', meanonly local expi = r(max) if `k' != 12 di as txt `i' "{col 15}{c |}" /// as res %9.0f `obsi' /// as res "{col 30}" %9.3f `expi' else di as txt "``i''" "{col 15}{c |}" /// as res %9.0f `obsi' /// as res "{col 30}" %9.3f `expi' } di as txt "{hline 14}{c BT}{hline 23}" } if `edwards' di _n as txt "Edwards test" else di as txt _n "Walter & Elwood test`exacttxt'" di _n as txt "Total number of cases = " as res `N' di _n as txt "Seasonality test" "{col 35}Goodness of fit test" local chitxt1 `"as txt "chi2(" as res "2" as txt ")""' local chitxt2 `"as txt "chi2(" as res "`= `k' -1'" as txt ")""' di `chitxt1' "{col 15}= " as res %9.4f `test' /// "{col 35}" `chitxt2' "{col 50}=" as res %9.4f `fit' di as txt "Prob > chi2" "{col 15}= " as res %9.4f chiprob(2,`test') /// as txt "{col 35}Prob > chi2" "{col 50}=" as res %9.4f chiprob(`k' - 1,`fit') di _n as txt "{hline 30}{c TT}{hline 9}" di as txt "Parameter" "{col 31}{c |} Estimate" di as txt "{hline 30}{c +}{hline 9}" di as txt "Amplitude of cyclic variation" "{col 31}{c |}" /// as res %9.3f `alpha' di as txt "Angle of maximum rate" "{col 31}{c |}" /// as res %9.1f `thstar' di as txt "Fraction of year" "{col 31}{c |}" /// as res %9.3f `foy' di as txt "{hline 30}{c BT}{hline 9}" return scalar foy = `foy' return scalar angmax = `thstar' return scalar amplitude = `alpha' return scalar chi2_seasonal = `fit' return scalar chi2_fit = `test' return scalar n_cases = `N' if "`generate'" != "" gen `generate' = `exp' end