*! version 1.0.2 20apr1996 program define svy_pars version 4.0 local name "`1'" if "`name'"=="save" { /* save macros */ MakeDeff /* make matrices S_E_deff, S_E_deft, S_E_meft */ matrix S_E_Vsrs = $S_VYdeff matrix S_E_Vmsp = $S_VYmeff matrix S_E_npop = $S_VYnsub matrix S_E_nobs = $S_VYosub matrix S_E_err = $S_VYerr if "$S_VYfpc"!="" { matrix S_E_Vswr = $S_VYdeft } if "$S_VYcomp"=="" { matrix S_E_b = $S_VYb matrix S_E_V = $S_VYv matrix S_E_nstr = $S_VYmstr matrix S_E_npsu = $S_VYmpsu } global S_E_nobs "$S_VYnobs" global S_E_nstr "$S_VYnstr" global S_E_npsu "$S_VYnpsu" global S_E_npop = $S_VYnpop /* scalar */ global S_E_nby "$S_VYnby" global S_E_by "$S_VYby" global S_E_lab "$S_VYlab" global S_E_miss "$S_VYmiss" global S_E_wgt "$S_VYwgt" global S_E_exp "$S_VYexp" global S_E_str "$S_VYstr" global S_E_psu "$S_VYpsu" global S_E_fpc "$S_VYfpc" global S_E_sub "$S_VYsub" global S_E_vl "$S_VYvl" global S_E_depv = upper(substr("$S_VYcmd",1,1)) + /* */ substr("$S_VYcmd",2,.) global S_E_cmd "svy$S_VYcmd" } /* Erase macros. */ global S_VYnobs /* number of obs */ global S_VYnstr /* number of strata */ global S_VYnpsu /* number of PSUs */ global S_VYnpop /* scalarname = sum of weights = pop. size */ global S_VYtype /* double or float for computation */ global S_VYwgt /* user's weight type */ global S_VYexp /* user's weight variable or expression */ global S_VYw /* weight variable to use in computations */ global S_VYstr /* user's strata variable */ global S_VYpsu /* user's psu variable */ global S_VYfpc /* user's fpc variable */ global S_VYsub /* user's subpop() expression */ global S_VYcmd /* svy* command */ global S_VYvl /* user's varlist */ global S_VYnvl /* # terms in varlist (ratio counts as 1) */ global S_VYopt /* user's other options */ global S_VYby /* user's by() varlist */ global S_VYnby /* # subpops formed with by()/subpop() */ global S_VYsrss /* = "srssubpop" if srssubpop specified */ global S_VYlab /* = "label" if labels for by() vars */ global S_VYmiss /* = "missing" if . found using available */ global S_VYb /* tempname for beta vector */ global S_VYv /* tempname for covariance matrix */ global S_VYdeff /* tempname for covariance matrix deff */ global S_VYdeft /* tempname for covariance matrix deft */ global S_VYmeff /* tempname for covariance matrix meff */ global S_VYnsub /* tempname for vector of subpop size */ global S_VYosub /* tempname for vector of subpop #obs */ global S_VYerr /* tempname for vector of error flags */ global S_VYmstr /* tempname for vector of #strata (available) */ global S_VYmpsu /* tempname for vector of #psu (available) */ global S_VYceq /* column equation names for matrices */ global S_VYcnam /* column names for matrices */ global S_VYcomp /* = "complete" if using complete cases */ if "`name'"=="save" | "`name'"=="cleanup" { exit } local doit "`2'" /* mark variable */ local w "`3'" /* weight variable (if needed) */ local nh "`4'" /* #PSUs per stratum */ local subvar "`5'" /* subpop category tempvar (if needed) */ global S_VYnpop "`6'" /* tempname for scalar of pop total */ global S_VYnsub "`7'" /* tempname for vector of subpop size */ global S_VYosub "`8'" /* tempname for vector of subpop #obs */ macro shift 8 /* Parse. */ local varlist "req ex" local weight "pweight iweight noprefix" local if "opt" local in "opt" #delimit ; local options "STRata(string) PSU(string) FPC(string) COMplete FLOAT AVailable BY(string) SUBpop(string) SRSsubpop noLABel Level(int $S_level) CI DEFF DEFT MEFF MEFT OBS SIZE" ; /* noWARNing" ; */ #delimit cr if "`name'"!="ratio" { parse "`*'" } else { ParseRat `*' parse "$S_VYvl" } if "`complet'"!="" & "`availab'"!="" { di in red "only one of complete and available can be " /* */ "specified" exit 198 } if "`srssubp'"!="" & "`by'`subpop'"=="" { di in red "srssubpop can only be specified when by() or " /* */ "subpop() is specified" exit 198 } if "`label'"!="" & "`by'"=="" { di in red "nolabel can only be specified when by() " /* */ "is specified" exit 198 } /* commented out /* Display warning about the use "if" or "in". */ if "`if'`in'"!="" & "`warning'"=="" { di _n in blu "Note: Use subpop(expression) option to " /* */ "obtain estimates for a subpopulation" _n /* */ "rather than " _quote "if" _quote " or " /* */ _quote "in" _quote "." } end commented out */ /* Set global macros. */ global S_VYcmd "`name'" global S_VYvl "`varlist'" global S_VYnvl : word count `varlist' if "`name'"=="ratio" { global S_VYnvl = $S_VYnvl/2 } global S_VYopt /* */ "level(`level') `ci' `deff' `deft' `meff' `meft' `obs' `size'" if "`float'"=="" { global S_VYtype "double" } else global S_VYtype "float" global S_VYsrss "`srssubp'" /* Get weights. */ if "`exp'"=="" { var_get pweight `exp', optional local exp "$S_1" } else if "`weight'"=="pweight" { /* try to varset pweight variable */ capture confirm variable `exp' if _rc==0 { var_get pweight `exp' local exp "$S_1" } } if "`exp'"!="" { global S_VYexp "`exp'" if "`weight'"!="" { global S_VYwgt "`weight'" } else global S_VYwgt pweight } /* Generate weights if necessary. */ capture confirm variable `exp' if _rc { if "`exp'"=="" { qui gen byte `w' = 1 } else qui gen double `w' = `exp' global S_VYw "`w'" } else global S_VYw "`exp'" /* Get strata, psu, and fpc. */ var_get strata `strata', optional global S_VYstr "$S_1" capture confirm string variable $S_VYstr if _rc==0 { local strata } else local strata "$S_VYstr" var_get psu `psu', optional global S_VYpsu "$S_1" capture confirm string variable $S_VYpsu if _rc==0 { local psu } else local psu "$S_VYpsu" var_get fpc `fpc', optional global S_VYfpc "$S_1" /* Process by() option. */ if "`by'"!="" { if "`label'"=="" { /* use labels if possible */ global S_VYlab "label" } unabbrev `by' global S_VYby $S_1 } /* Mark. */ mark `doit' `if' `in' /* Check for negative weights if pweights. */ if "$S_VYwgt"=="pweight" { capture assert $S_VYw >= 0 if `doit' if _rc { error 402 } } /* Markout. */ if $S_VYnvl==1 & "`availab'"=="" { local complet "complete" } markout `doit' $S_VYw `strata' `psu' $S_VYfpc $S_VYby capture confirm string variable $S_VYstr if _rc==0 { /* markout string S_VYstr */ qui replace `doit' = 0 if trim($S_VYstr)=="" } capture confirm string variable $S_VYpsu if _rc==0 { /* markout string S_VYpsu */ qui replace `doit' = 0 if trim($S_VYpsu)=="" } if "`complet'"!="" { markout `doit' $S_VYvl } else if "`availab'"=="" { /* give it a chance to be complete */ tempvar doit2 mark `doit2' if `doit' markout `doit2' $S_VYvl capture assert `doit'==`doit2' if _rc==0 { local complet "complete" } } global S_VYcomp "`complet'" /* Compute total #obs. */ qui count if `doit' if _result(1) == 0 { error 2000 } global S_VYnobs = _result(1) /* `subvar' = 1 for observations satisfying subpop(); otherwise 0. */ if "`subpop'"!="" { capture gen byte `subvar' = (`subpop') if `doit' if _rc { if _rc != 902 { di in red "error in expression in " /* */ "subpop() option" } error _rc } qui count if `subvar' & `doit' if _result(1) == 0 { error 2000 } global S_VYnby 1 global S_VYsub "`subpop'" } else if "$S_VYby"!="" { qui gen byte `subvar' = 1 if `doit' } else { /* no subpopulations */ local subvar } /* Set `subvar' variable and get labels if by() specified. */ if "$S_VYby"!="" { GenSub `doit' `subvar' $S_VYby } /* Generate `nh' variable and numbers of strata, psu, population. */ Gen_nh `doit' `nh' `subvar' end program define ParseRat version 4.0 parse "`*'", parse(" /[,(") local last 0 local nvar 0 local i 1 while "``i''"!="," & "``i''"!="[" & "``i''"!="if" /* */ & "``i''"!="in" & "``i''"!="" { if "``i''"=="/" { if `last' | mod(`nvar',2)==0 { error 198 } local last 1 local `i' " " } else { local last 0 local nvar = `nvar' + 1 } local i = `i' + 1 } if mod(`nvar',2)!=0 { di in red "must have an even number of variables" error 198 } global S_VYvl "`*'" end program define GenSub /* If there is one variable in by(), labels are put in S_VYcnam; if variable is labeled, these labels are used; otherwise, the variable's values are used. If there are two variables in by() and they are both labeled, the labels are put in S_VYlab. */ version 4.0 local doit "`1'" local subvar "`2'" macro shift 2 tempvar sub if "$S_VYlab"=="" { /* user specified nolabel */ local nolabel "nolabel" } quietly { sort `doit' `subvar' `*' by `doit' `subvar' `*': gen byte `sub' = (_n==1) /* */ if `subvar' & `doit' replace `subvar' = sum(`sub') if `subvar' & `doit' global S_VYnby = `subvar'[_N] } local nvar : word count `*' if `nvar' == 1 { GenLab1 `subvar' `*' exit } else if `nvar'==2 & "$S_VYlab"!="" { GenLab2 `subvar' `*' if "$S_VYlab"!="" { exit } } capture noisily { rename `subvar' _Subpop list _Subpop `*' if _Subpop != _Subpop[_n-1], noobs `nolabel' } nobreak { if _rc { local rc = _rc capture drop _Subpop exit `rc' } rename _Subpop `subvar' } end program define GenLab1 /* Puts labels in global macro S_VYcnam. */ version 4.0 local subvar "`1'" local x "`2'" tempvar sub strx local type : type `subvar' qui gen `type' `sub' = `subvar' /* */ if `subvar'!=`subvar'[_n-1] & `subvar' > 0 if "$S_VYlab"!="" { local label : value label `x' if "`label'"!="" { Decode `sub' `x' `strx' } else global S_VYlab } sort `sub' local i 1 while `i' <= $S_VYnby { if "`label'"!="" { local tag = `strx'[`i'] } else local tag if "`tag'"=="" { local value = `x'[`i'] local tag = substr("`value'",1,8) } global S_VYcnam "$S_VYcnam `tag'" local i = `i' + 1 } end program define GenLab2 /* Puts labels in global macro S_VYlab. */ version 4.0 local subvar "`1'" local x1 "`2'" local x2 "`3'" tempvar sub strx1 strx2 local type : type `subvar' global S_VYlab local lab1 : value label `x1' local lab2 : value label `x2' if "`lab1'"=="" | "`lab2'"=="" { exit } qui gen `type' `sub' = `subvar' /* */ if `subvar'!=`subvar'[_n-1] & `subvar' > 0 Decode `sub' `x1' `strx1' Decode `sub' `x2' `strx2' sort `sub' local i 1 while `i' <= $S_VYnby { local tag1 = `strx1'[`i'] if "`tag1'"=="" { local value = `x1'[`i'] local tag1 = substr("`value'",1,8) } local tag2 = `strx2'[`i'] if "`tag2'"=="" { local value = `x2'[`i'] local tag2 = substr("`value'",1,8) } global S_VYlab "$S_VYlab `tag1' `tag2'" local i = `i' + 1 } end program define Decode version 4.0 local flag "`1'" local x "`2'" local str "`3'" tempvar sp quietly { decode `x' if `flag'!=., gen(`str') replace `str' = trim(`str') if `flag'!=. /* Check for = signs. This should be omitted when "matrix colnames" fixed. */ gen byte `sp' = index(`str',"=") if `flag'!=. capture assert `sp'==0 | `sp'==. if _rc { di in red "= signs not allowed in value labels" exit 503 } drop `sp' /* end of code to be omitted when "matrix colnames" fixed. */ local i 1 while `i' <= 8 { gen byte `sp' = index(`str'," ") if `flag'!=. summarize `sp' if _result(6) == 0 { exit } replace `str' = substr(`str',1,`sp'-1) + "_" /* */ + substr(`str',`sp'+1,.) if `sp'>0 & `sp'!=. drop `sp' local i = `i' + 1 } } end program define Gen_nh version 4.0 local doit "`1'" local nh "`2'" local subvar "`3'" quietly { sort `doit' $S_VYstr $S_VYpsu $S_VYw /* Compute total #strata. */ by `doit' $S_VYstr: gen byte `nh' = (_n==1) if `doit' count if `nh' == 1 global S_VYnstr = _result(1) /* `nh' = #PSU in stratum h */ if "$S_VYpsu"!="" { by `doit' $S_VYstr $S_VYpsu: replace `nh' = (_n==1) /* */ if `doit' } else { /* observations are PSUs */ replace `nh' = 1 if `doit' } /* Compute total #PSU. */ count if `nh' == 1 global S_VYnpsu = _result(1) /* Finish `nh' computation. Note: automatic promotion of type. */ by `doit' $S_VYstr: replace `nh' = sum(`nh') if `doit' by `doit' $S_VYstr: replace `nh' = `nh'[_N] if `doit' /* Check if `nh' >= 2. */ capture assert `nh' >= 2 if `doit' if _rc { di in red "stratum with only one PSU detected" exit 499 } /* Check fpc variable for sensible ranges. */ if "$S_VYfpc"!="" { CheckFPC `doit' $S_VYstr $S_VYfpc `nh' } /* Compute sum of weights. */ GenSum $S_VYnpop `doit'*$S_VYw if "$S_VYcomp"=="" { exit } /* If here, we are doing complete-case computation. */ if "`subvar'"=="" { matrix $S_VYosub = ($S_VYnobs) matrix $S_VYnsub = (0) matrix $S_VYnsub[1,1] = $S_VYnpop } else { /* we have subpops */ tempname s matrix $S_VYnsub = J(1,$S_VYnby,0) matrix $S_VYosub = J(1,$S_VYnby,0) local isub 1 while `isub' <= $S_VYnby { GenSum `s' (`subvar'==`isub')*$S_VYw matrix $S_VYnsub[1,`isub'] = `s' count if `subvar'==`isub' matrix $S_VYosub[1,`isub'] = _result(1) local isub = `isub' + 1 } } tempname A matrix `A' = J(1,$S_VYnvl,1) matrix $S_VYnsub = `A' # $S_VYnsub matrix $S_VYosub = `A' # $S_VYosub } end program define CheckFPC version 4.0 local doit "`1'" local strata "`2'" local fpc "`3'" local nh "`4'" capture assert `fpc' >= 0 if `doit' if _rc { di in red "fpc() must be >= 0" exit 499 } capture by `doit' `strata': assert abs((`fpc' - `fpc'[1]) /* */ /max(`fpc'[1],1)) < 1e-5 if `doit' if _rc { di in red "all observations within a stratum must have " /* */ "the same fpc() value" exit 499 } capture assert `fpc' >= `nh' if `doit' if _rc { capture assert `fpc' <= 1 if `doit' if _rc { di in red "fpc() must be <= 1 if a rate " /* */ "or >= # sampled PSUs per stratum" exit 499 } } end program define GenSum /* scalarname expression */ version 4.0 local s "`1'" macro shift tempvar y e quietly { gen double `y' = sum(`*') gen double `e' = sum((`*')-(`y'-`y'[_n-1])) in 2/l scalar `s' = `y'[_N] + `e'[_N] } end program define MakeDeff version 4.0 if "$S_VYcomp"!="" { tempname V matrix `V' = get(VCE) matrix `V' = vecdiag(`V') local ii "\$_i" } else { local V "$S_VYv" local ii 1 } if "$S_VYfpc"!="" { local Vdeft "$S_VYdeft" } else local Vdeft "$S_VYdeff" local dim = colsof(`V') matrix S_E_deff = `V' matrix S_E_deft = `V' matrix S_E_meft = `V' local i 1 while `i' <= `dim' { matrix S_E_deff[1,`i'] = cond($S_VYdeff[`ii',`i']!=0, /* */ `V'[1,`i']/$S_VYdeff[`ii',`i'], 0) matrix S_E_deft[1,`i'] = cond(`Vdeft'[`ii',`i']!=0, /* */ sqrt(`V'[1,`i']/`Vdeft'[`ii',`i']), 0) matrix S_E_meft[1,`i'] = cond($S_VYmeff[`ii',`i']!=0, /* */ sqrt(`V'[1,`i']/$S_VYmeff[`ii',`i']), 0) local i = `i' + 1 } end