*! version 5.0.0 12jul2000 Special version for Andy Sloggert program define glm2, eclass version 6.0 if replay() { Playback `0' exit } syntax varlist [if] [in] [aw fw iw] [, LEvel(int $S_level) EForm /* */ LTol(real -1) ITerate(int 0) /* */ Family(string) Link(string) DISP(real 1) Scale(string) /* */ FRVars Offset(varname numeric) LNOffset(varname numeric) /* */ noCONStant INIt(varname numeric) noLOg ] marksample touse /* must be done early */ if `"`log'"'!="" { local iflog `"*"' } else local iflog "noi" if `"`constan'"'!="" { local cons "nocons" } local small 1e-6 if `level'<10 | `level'>99 { local level 95 } if `ltol'<0 { local ltol 1e-6 } /* was 1e-8 in glmr (sg22)-too small */ if `iterate'<=0 { local iterate 50 } /* Validate family and set up link indicator (MapFL is why touse must be resolved so soon) */ MapFL `"`family'"' `"`link'"' local family `"`r(family)'"' local link `"`r(link)'"' local pow `r(power)' local scale1 `r(scale)' /* 1 for fams with default scale param 1 */ local m `r(m)' local mfixed `r(mfixed)' local k `r(k)' local bernoul = `mfixed' & `"`m'"'=="1" /* Bernoulli dist */ local reg = `"`family'"'=="gau" & `"`pow'"'=="1" if `reg' { local iterate 1 } /* Values of `scale' used: ------------------------------------------- "`scale'" known scale unknown scale ------------------------------------------- "" (default) "" => 1 "" => dispc dev -1 => dispd -1 => dispd x2 0 => dispc 0 => dispc # # # ------------------------------------------- */ if `"`scale'"'!="" { if `"`scale'"'=="x2" { local scale 0 } else if `"`scale'"'=="dev" { local scale -1 } else { capture confirm number `scale' if _rc { di in red "invalid scale()" exit 198 } } } local efopt `"`eform'"' if `"`eform'"'!="" { MapEform `family' `"`link'"' local eform `"`r(eform)'"' } tempvar mu eta W z V dev wt quietly { tokenize `varlist' local y `"`1'"' mac shift /* Deal with missing values of binomial denominator variable (m). */ if !`mfixed' { local mmiss `"`m'"' } /* Offset / log offset */ if `"`lnoffse'"'!="" { if `"`offset'"'!="" { error 198 } tempvar offvar local offstr `"ln(`lnoffse')"' gen double `offvar' = `offstr' } else if `"`offset'"'!="" { local offvar `"`offset'"' local offstr `"`offset'"' } if `"`offstr'"'!="" { local offopt `", offset `offstr'"' } if `"`link'"'=="ht" { local mpow `"`pow'"' } markout `touse' `offvar' `mmiss' `mpow' sum `y' if `touse' /* purposely not weighted */ if r(N)==0 { noisily error 2000 } if r(N)==1 { noisily error 2001 } if r(min)==r(max) & `"`offstr'"'=="" { noi di _n in bl "outcome does not vary" exit 2002 } local nobs = r(N) /* nobs reset below when fweights */ if `"`weight'"'!="" { gen double `wt' `exp' if `touse' if `"`weight'"'=="aweight" { summ `wt' replace `wt' = `wt'/r(mean) } else if `"`weight'"'=="fweight" { summ `touse' [fw=`wt'] if `touse' local nobs = round(r(N),1) } } else gen byte `wt' = `touse' if `touse' /* check family(binomial) for sensibility of dependent variable */ if `"`family'"'=="bin" { capture assert `y'>=0 if `touse' if _rc { di in red `"dependent variable `y' has negative values"' exit 499 } if `mfixed'==0 { capture assert `m'>0 if `touse' /* sic, > */ if _rc { di in red `"`m' has nonpositive values"' exit 499 } capture assert `m'==int(`m') if `touse' if _rc { di in red `"`m' has noninteger values"' exit 499 } } capture assert `y'<=`m' if `touse' if _rc { di in red `"`y' > `m' in some cases"' exit 499 } } /* Initialization: tolerance, iterations, mean (mu), working vectors */ if `"`init'"'!="" { gen double `mu' = `init' if `touse' } else { sum `y' [aw=`wt'] if `touse' gen double `mu' = (`y'+r(mean))/(`m'+1) } gen double `W' = . in 1 gen double `z' = . in 1 gen double `V' = . in 1 gen double `dev' = . in 1 /* Initialise linear predictor */ if `"`link'"'!="pow" { if `"`family'"'=="bin" { if `"`init'"'=="" { replace `mu' = `m'*(`y'+.5)/(`m'+1) /* */ if `touse' } if `"`link'"'=="l" { gen double `eta' = ln(`mu'/(`m'-`mu')) } else if `"`link'"'=="p" { gen double `eta' = invnorm(`mu'/`m') } else if `"`link'"'=="c" { gen double `eta' = ln(-ln(1-`mu'/`m')) } else if `"`link'"'=="ht" { gen double `eta' = ln(-ln(`mu'/`m')+ln(`pow')) } if `"`link'"'=="opo" { gen double `eta' = /* */ cond(abs(`pow')<`small', /* */ ln(`mu'/(`m'-`mu')), /* */ ((`mu'/(`m'-`mu'))^`pow'-1)/`pow') } } if `"`family'"'=="gau" { gen double `eta' = `mu' } else if `"`family'"'=="poi" { gen double `eta' = ln(`mu') } else if `"`family'"'=="gam" { gen double `eta' = 1/`mu' } else if `"`family'"'=="ivg" { gen double `eta' = 1/`mu'^2 } else if `"`family'"'=="nb" { gen double `eta' = -ln(1 + 1/(`k'*`mu')) } } else { if abs(`pow')<`small' { gen double `eta' = ln(`mu') } else gen double `eta' = `mu'^`pow' } /* Local scoring algorithm: IRLS */ tempname newdev oldev Wscale scalar `oldev' = 0 scalar `newdev' = 1 local i 1 `iflog' di while abs(`newdev'-`oldev')>`ltol' & `i'<=`iterate' { scalar `oldev' = `newdev' /* Get 1/(d(eta)/d(mu)) and iterative weights, W. (Up to a constant, these are the same for canonical link functions.) Also calculate the adjusted independent variable, z. */ CalcV `touse' `y' `family' `"`link'"' `pow' `m' /* */ `disp' `k' `eta' `mu' `W' `z' `V' `"`offvar'"' /* Weighted regression `Wscale' added by wms 10 Apr 1995 */ summarize `W' [aw=`wt'] scalar `Wscale' = r(mean) regress `z' `*' [iw=`W'*`wt'/`Wscale'], mse1 `cons' /* Get linear predictor */ cap drop `eta' _predict double `eta' if `touse' if `"`offstr'"'!="" { replace `eta' = `eta'+`offvar' } /* Get inverse link */ est local family `"`family'"' est local link `"`link'"' global S_E_fam `"`family'"' /* double save */ global S_E_link `"`link'"' _crcgli2 `eta' `mu' `pow' `m' `k' `bernoul' count if `mu'==. & `eta' != . & `touse' if r(N) != 0 { noi di in red "estimates diverging" exit 430 } /* Get weighted squared deviance contributions (residuals) */ _crcgldv `y' `family' `bernoul' `m' `k' `mu' `wt' `dev' /* Get deviance (note: analytic weights are already normalized). */ replace `z' = sum(`dev') scalar `newdev' = `z'[_N]/`disp' `iflog' di in gr `"Iteration `i' : deviance = "' /* */ in ye %9.4f `newdev' local i = `i'+1 } local conrc = cond(abs(`newdev'-`oldev')>`ltol' & !`reg',430,0) if `conrc' { noisily di in ye "(convergence not achieved)" } /* Get weighted squared contributions (residuals) to Pearson X2 */ replace `z' = sum(`wt'*(`y'-`mu')^2/`V') local chisq = `z'[_N]/`disp' local df = `nobs'-e(df_m)-(`"`cons'"'=="") local dispc = `chisq'/`df' local dispd = `newdev'/`df' } /* Store results */ DescFL `"`family'"' `"`link'"' `pow' `bernoul' `k' `m' local o `"`r(dist)', `r(link)'`offopt'"' if `"`scale'"'=="" { /* default */ local scale `scale1' if `scale1' { local delta 1 } else local delta `dispc' } else if `scale'==0 { /* Pearson X2 scaling */ local delta `dispc' if `scale1' { local cd "square root of Pearson X2-based dispersion" } } else if `scale'==-1 { /* deviance scaling */ local delta `dispd' local cd "square root of deviance-based dispersion" } else { /* user's scale parameter */ local delta `scale' if !`scale1' | (`scale1' & `scale'!=1) { local cd `"dispersion equal to square root of `delta'"' } } if !`scale1' | (`scale1' & `scale'!=1) { if `scale1' { local dof 100000 } else local dof `df' if `delta'==. { local zapse "yes" } else scalar `Wscale' = `Wscale'/`delta' /* scale to `delta' */ } tempname b V if `reg' { local dofopt `"dof(`df')"' } mat `b' = get(_b) mat `V' = get(VCE) scalar `Wscale' = 1/`Wscale' mat `V' = `Wscale'*`V' /* get rid of `Wscale' scaling */ if `"`zapse'"'=="yes" { local i 1 while `i'<=rowsof(`V') { mat `V'[`i',`i'] = 0 local i=`i'+1 } } tempvar mysamp qui gen byte `mysamp' = `touse' est post `b' `V', depname(`y') obs(`nobs') `dofopt' esample(`mysamp') /* results can be saved now */ /* double save in S_E_ and e() */ if `"`cd'"'!="" { est local msg_1 `"(Standard errors scaled using `cd')"' global S_E_msg1 `"(Standard errors scaled using `cd')"' } if `reg' { est local msg_2 "(Model is ordinary regression, use regress instead)" global S_E_msg2 "(Model is ordinary regression, use regress instead)" } if `disp'!=1 { est local msg_3 `"(Quasi-likelihood model with dispersion `disp')"' global S_E_msg3 `"(Quasi-likelihood model with dispersion `disp')"' } if `"`frvars'"'!="" { cap drop _mu cap drop _eta cap drop _dres gen _dres = sign(`y'-`mu')*sqrt(`wt'*`dev'/`delta') if `touse' rename `mu' _mu rename `eta' _eta lab var _mu `"E(`y')"' lab var _eta "Linear predictor" lab var _dres "Scaled deviance-residuals" } /* Save results -- new gould */ /* double save in S_E_ and e() (actually triple save in S_#) */ est scalar df_pear = `df' est scalar N = `nobs' est scalar chi2 = `chisq' est scalar deviance = `newdev' est scalar dispersp = `dispc' est scalar dispers = `dispd' global S_E_rdf `df' global S_E_nobs `nobs' global S_E_chi2 `chisq' global S_E_dev = `newdev' global S_E_dc `dispc' global S_E_dd `dispd' global S_1 `nobs' global S_2 `df' global S_3 = `newdev' global S_4 `chisq' /* Save more results (for glmrpred) -- new Royston 4/94. */ /* more double saves in S_E_ and e() */ est local wtype `"`weight'"' est local wexp `"`exp'"' est local family `"`family'"' est local link `"`link'"' est local title_fl `"`o'"' est scalar bernoul = `bernoul' est local m `"`m'"' est local depvar `"`y'"' est scalar power = `pow' if ("`link'"=="ht") { est local power = "`pow'" } est local offset `"`offstr'"' /* offset/lnoffset */ est scalar lnoffset = `"`lnoffse'"'!="" /* 1 if lnoffset, 0 otherwise */ est local eform `"`eform'"' est scalar k = `k' est scalar disp = `disp' est scalar delta = `delta' est scalar rc = `conrc' global S_E_vl `"`varlist'"' global S_E_if `"`if'"' global S_E_in `"`in'"' global S_E_wgt `"`weight'"' global S_E_exp `"`exp'"' global S_E_fam `"`family'"' global S_E_link `"`link'"' global S_E_flo `"`o'"' global S_E_ber `bernoul' global S_E_m `"`m'"' global S_E_depv `"`y'"' global S_E_pow `"`pow'"' global S_E_off `"`offstr'"' /* offset/lnoffset */ global S_E_lno = `"`lnoffse'"'!="" /* 1 if lnoffset, 0 otherwise */ global S_E_ef `"`eform'"' global S_E_k `"`k'"' global S_E_disp `"`disp'"' global S_E_del `"`delta'"' global S_E_rc `conrc' est local predict "glm_p2" est local cmd "glm" global S_E_cmd "glm" /* must be last */ Playback, level(`level') `efopt' end program define Playback syntax [, LEvel(int $S_level) EForm] if `"`e(cmd)'"'!="glm" { error 301 } if `level'<10 | `level'>99 { di in red "level() must be between 10 and 99" exit 198 } #delimit ; di _n in gr "Residual df = " in ye %9.0g e(df_pear) _col(57) in gr "No. of obs = " in ye %9.0g e(N) ; di in gr "Pearson X2 = " in ye %9.0g e(chi2) in gr _col(57) "Deviance = " in ye %9.0g e(deviance) ; di in gr "Dispersion = " in ye %9.0g e(dispersp) in gr _col(57) "Dispersion = " in ye %9.0g e(dispers) ; #delimit cr di in gr _n `"`e(title_fl)'"' /* family, link, offset */ if `"`eform'"'!="" { MapEform `e(family)' `"`e(link)'"' est di, level(`level') `r(eform)' } else est di, level(`level') local i 1 while `i' <= 3 { if `"`e(msg_`i')'"' != "" { di in gr `"`e(msg_`i')'"' } local i = `i' + 1 } error `e(rc)' end program define MapEform, rclass args fam link if `"`link'"'=="l" | `"`link'"'=="opo" { local eform "eform(Odds Ratio)" } else if `"`link'"'=="p" | `"`link'"'=="c" { local eform "eform(ExpB)" } else if (`"`fam'"'=="poi") { local eform "eform(IRR)" } else local eform "eform(e^coef)" ret local eform `eform' end program define MapFL, rclass /* family link */ args f ulink MapFam tocode `f' /* map user-specified family */ local fam `"`r(famcode)'"' /* store code in fam */ local mfixed 1 local m 1 local k 1 if `"`fam'"'=="bin" { /* bin takes an optional argument */ tokenize `"`f'"' if `"`2'"'!="" { capture confirm integer number `2' if _rc { unabbrev `2' local m `"`s(varlist)'"' local mfixed 0 } else { if `2'==. | `2'<=0 { di in red /* */ `"`2' in family(binomial `2') invalid"' exit 198 } local m `2' } } } if `"`fam'"'=="nb" { /* nb takes an optional argument */ tokenize `"`f'"' if `"`2'"' != "" { confirm number `2' if `2'<=0 { di in red /* */ `"`2' in family(nbinomial `2') invalid"' exit 198 } local k `2' } } MapLink tocode `ulink' local link `"`r(link)'"' local pow `"`r(power)'"' /* Apply default links and then check for allowed links fam default link allowed links --------------------------------------------- gau pow 1 pow # bin l l, p, c, pow #, opo # poi pow 0 pow # nb pow 0 nb, pow # gam pow -1 pow # ivg pow -2 pow # */ local scale1 = `"`fam'"'=="bin" | `"`fam'"'=="nb" | `"`fam'"'=="poi" if `"`link'"'=="" { /* apply defaults */ local link "pow" if `"`fam'"'=="gau" { local pow 1 } else if `"`fam'"'=="bin" { local link "l" } else if `"`fam'"'=="gam" { local pow -1 } else if `"`fam'"'=="ivg" { local pow -2 } else if `"`fam'"'=="poi" { local pow 0 } else if `"`fam'"'=="nb" { local pow 0 } else local link /* comment by wwg: the remaining defaults are applied someplace else in the code and, moreoever, "family(gam)" produces the description "Gamma distribution, canonical link" while the equivalent "family(gam) link(pow -1)" produces "Gamma distribution, power link (power = -1)". This should be considered a bug. I would like to see all the defaults set right here. comment by wwg: I do not fully understand the [above] restriction and am not convinced it excludes all the cases it should. response by jpr, 26-Jan-94 -------------------------- 1. I have now set up all default links arising from null user link. 2. We already know from previous checks that `link' must be one of id, log, pow, opo, nb, l, c or p. Remains to check that l, c, p or opo are used only with binomial family. */ } else { /* check valid fam/link combination */ local binlink = `"`link'"'=="c" | `"`link'"'=="l" | /* */ `"`link'"'=="p" | `"`link'"'=="opo" | `"`link'"'=="ht" if (`"`fam'"'=="bin" & !(`binlink' | `"`link'"'=="pow")) | /* */ (`"`fam'"'!="bin" & `binlink' ) { di in red `"link `link' invalid with family `fam'"' exit 198 } } * di `"returns fam |`fam'| link |`link'| pow |`pow'|"' * di `" scale1 |`scale1'| m |`m'| mfixed |`mfixied'|"' ret local family `"`fam'"' ret local link `"`link'"' ret local power `pow' ret local scale `scale1' ret local m `m' ret local mfixed `mfixed' ret local k `k' end program define MapFam, rclass /* {tocode | fromcode} ... */ if `"`1'"'=="fromcode" { di in red "MapFam fromcode not yet implemented" exit 9000 } local s1 local f = lower(trim(`"`2'"')) local l = length(`"`f'"') if `"`f'"'=="" { local s1 "gau" } else if `"`f'"'==substr("binomial",1,`l') { local s1 "bin" } else if `"`f'"'==substr("bernoulli",1,`l') { local s1 "bin" } else if `"`f'"'==substr("gamma",1,max(`l',3)) { local s1 "gam" } else if `"`f'"'==substr("gaussian",1,max(`l',3)) { local s1 "gau" } else if `"`f'"'==substr("igaussian",1,max(`l',2)) { local s1 "ivg" } else if `"`f'"'==substr("inormal",1,max(`l',2)) { local s1 "ivg" } else if `"`f'"'=="ivg" { local s1 `"`ivg'"' } else if `"`f'"'==substr("normal",1,`l') { local s1 "gau" } else if `"`f'"'==substr("nbinomial",1,max(2,`l')) { local s1 "nb" } else if `"`f'"'==substr("poisson",1,`l') { local s1 "poi" } else { di in red `"unknown family() `f'"' exit 198 } if `"`s1'"'=="bin" | `"`s1'"'=="nb" { local last 4 } else local last 3 if `"``last''"'!="" { di in red "family() invalid" exit 198 } ret local famcode `s1' end /* Map user-specified family `f' to internal family code `fam'. (Capitalization indicates minimum abbreviations.) mapped to Allowed (fam) ----------------------------------- gau Binomial bin Bernoulli bin GAMma gam GAUssian gau IGaussian ivg INormal ivg IVG ivg (for backwards capatibility) Normal gau NBinomial nb Poisson poi */ program define MapLink, rclass /* {tocode | fromcode ..} ... */ if `"`1'"'=="fromcode" { di in red "MapLink fromcode not yet implemented" exit 9000 } local ulink = lower(`"`2'"') local upow `"`3'"' if `"`4'"'!="" { di in red "link() invalid" exit 198 } local l = length(`"`ulink'"') local s1 "pow" /* returned link */ local s2 . /* returned power if link is pow */ if `"`ulink'"'=="" { local s1 } else if `"`ulink'"'==substr("identity",1,`l') { local s2 1 } else if `"`ulink'"'=="log" { local s2 0 } else if `"`ulink'"'==substr("power",1,max(`l',3)) { capture confirm number `upow' if _rc { di in red "invalid # in link(power #)" exit 198 } local s2 `upow' local upow } else if `"`ulink'"'==substr("opower",1,max(`l',3)) { capture confirm number `upow' if _rc { di in red "invalid # in link(opower #)" exit 198 } if `upow'==0 { local s1 "l" } else { local s1 "opo" /* short for odds-power */ local s2 `upow' } local upow } else if `"`ulink'"'==substr("ht",1,`l') { capture confirm variable `upow' if _rc { di in red "invalid variable in link(ht varname)" exit 198 } capture assert ((`upow'<=1)&(`upow'>0))|(`upow'==.) if _rc { di in red "expected survival probabilities must be between 0 and 1 in link(ht varname)" exit 198 } else { local s1 "ht" /* short for Hakulinen-Tenkanen */ local s2 `upow' } local upow } else if `"`ulink'"'==substr("logit",1,`l') { local s1 "l" } else if `"`ulink'"'==substr("probit",1,`l') { local s1 "p" } else if `"`ulink'"'==substr("cloglog",1,`l') { local s1 "c" } else if `"`ulink'"'==substr("nbinomial",1,`l') { local s1 "nb" } else { di in red `"unknown link() `ulink'"' exit 198 } if `"`upow'"'!="" { di in red `"unknown 2nd argument in link(`ulink' `upow')"' exit 198 } ret local link `s1' ret local power `s2' end /* Map user-specified link to internal link code. (Capitalization indicates minimum abbreviations.) mapped to Allowed (link) (pow) ----------------------------------------- Identity pow 1 LOG pow 0 Logit l Probit p Cloglog c POWer # pow # OPOwer # opo # (nothing) */ program define DescFL, rclass /* return description of family and link */ args f l pow bernoul k m local s1 " distribution" local s2 " link" if `"`f'"'=="gau" { local s1 `"Gaussian (normal)`s1'"' } else if `"`f'"'=="bin" & `bernoul' { local s1 `"Bernoulli`s1'"' } else if `"`f'"'=="bin" { local s1 `"Binomial (N=`m')`s1'"' } else if `"`f'"'=="poi" { local s1 `"Poisson`s1'"' } else if `"`f'"'=="gam" { local s1 `"Gamma`s1'"' } else if `"`f'"'=="ivg" { local s1 `"Inverse Gaussian`s1'"' } else if `"`f'"'=="nb" { local myk = round(`k',.0001) local s1 `"Negative Binomial (k=`myk')`s1'"' } if `"`l'"'=="pow" { if `"`pow'"'=="1" { local s2 `"identity`s2'"' } else if `"`pow'"'=="0" { local s2 `"log`s2'"' } else local s2 `"power`s2' (power = `pow')"' } if `"`l'"'=="opo" { if `"`pow'"'=="1" { local s2 `"identity odds-power`s2'"' } else if `"`pow'"'=="0" { local s2 `"logit`s2'"' } else local s2 `"odds-power`s2' (power = `pow')"' } else if `"`l'"'=="l" { local s2 `"logit`s2'"' } else if `"`l'"'=="p" { local s2 `"probit`s2'"' } else if `"`l'"'=="c" { local s2 `"cloglog`s2'"' } else if `"`l'"'=="ht" { local s2 `"Hakulinen and Tenkanen`s2'"' } else if `"`l'"'=="nb" { local s2 `"`s2' -ln(1 + 1/(k*mu))"' } ret local dist `"`s1'"' ret local link `"`s2'"' end * Update of _glmwgt (sg16.3), PR 22-Dec-93, 11-Apr-94, 11-Oct-94. * Calculates var functn, iterative weights and working dependent variable. program define CalcV args touse y fam link pow m disp k eta mu W z V moffset if `"`moffset'"'!="" { local moffset `"-`14'"' } local small 1e-6 /* Calculate variance function, V, for each family */ tempvar w if `"`fam'"'=="bin" { replace `V' = `mu'*(1-`mu'/`m') } else if `"`fam'"'=="gam" { replace `V' = `mu'^2 } else if `"`fam'"'=="gau" { replace `V' = 1 } else if `"`fam'"'=="ivg" { replace `V' = `mu'^3 } else if `"`fam'"'=="nb" { replace `V' = (`mu'+`k'*`mu'^2) } else if `"`fam'"'=="poi" { replace `V' = `mu' } /* Calc w = 1/{d(eta)/d(mu)} and W = w^2/V for each link/family, where V = variance function, noting W = abs(w) for canonical links. */ if `"`link'"'=="pow" { if abs(`pow')<`small' { gen double `w' = `mu' } else { gen double `w' = `m'^`pow'/(`pow'*`mu'^(`pow'-1)) } } else { if `"`fam'"' == "bin" { if `"`link'"' == "l" { gen double `w' = `V' } else if `"`link'"' == "p" { gen double `w' = `m'*exp(-.5*`eta'*`eta') /* */ /sqrt(2*_pi) if `touse' } else if `"`link'"' == "c" { gen double `w' = -`m'*(1-`mu'/`m')*log(1-`mu'/`m') } else if `"`link'"' == "ht" { gen double `w' = ln(`mu'/(`m'*`pow'))*`mu' } else if `"`link'"' == "opo" { gen double `w' = cond( abs(`pow'-1)<`small', /* */ `m'*(1-`mu'/`m')^2, /* */ `m'*( (`mu'/`m')^(1-`pow') )* /* */ (1-`mu'/`m')^(`pow'+1) ) } } else if `"`fam'"' == "gam" { gen double `w' = -`V' } else if `"`fam'"' == "ivg" { gen double `w' = -.5*`V' } else if `"`fam'"' == "nb" { gen double `w' = `V' } else if `"`fam'"' == "poi" { gen double `w' = `V' } } replace `W' = `disp'*`w'^2/`V' /* `disp' could be in wrong place */ replace `z' = `eta'+(`y'-`mu')/`w' `moffset' end