* Version 1.0.0 - 14 November 2017 * By Johannes S. Kunz, Kevin E. Staub & Rainer Winkelmann * See helpfile for explanations. * Please email kevin.staub@unimelb.edu.au for help or support. * The software is provided as is, without warranty of any kind, express or implied, including * but not limited to the warranties of merchantability, fitness for a particular purpose and * noninfringement. In no event shall the authors be liable for any claim, damages or other * liability, whether in an action of contract, tort or otherwise, arising from, out of or in * connection with the software or the use or other dealings in the software. cap program drop brglm program brglm, eclass sortpreserve version 14.0 syntax varlist(numeric ts fv) [if] [in] [ , MODEL(string) ITERate(integer 5000) /// TOLerance(real 1.000e-6) *] tempvar nobs depn eta mu dmudeta v w z xb qi hi touse tempname b V bold tol maxiter val VAL iter bold ystar converged logl ll if "`model'" == "" local model "probit" else if !inlist("`model'", "probit", "logit", "cloglog") { di as err "must choose model probit, logit, or cloglog" exit 198 } gettoken lhs rhs : varlist _fv_check_depvar `lhs' //check for factor variables _rmcoll `rhs', expand //check and not collinearities marksample touse // if `touse' `in' used to drop missings in covariate, does not work yet * Initial values for eta from OLS qui reg `lhs' `rhs' if `touse', `options' qui predict `eta' if `touse' , xb mat `bold' = e(b) sca `tol' = `tolerance' // tolerance level for convergence sca `maxiter' = `iterate' // maximum number of iterations * Entering WLS loop sca `val' = 1 // initialising convergence value local iter = 0 // initialising iteration number while `val'>`tol' & `iter'<`maxiter' { if "`model'"=="probit" { qui g double `mu' = normal(`eta') qui g double `dmudeta' = normalden(`eta') qui g double `v' = `mu'*(1-`mu') } if "`model'"=="cloglog" { qui g double `mu' = 1 - exp( -exp(`eta') ) //pi qui g double `dmudeta' = (1-`mu')*exp(`eta') //d qui g double `v' = (1-`mu')*`mu' } if "`model'"=="logit" { qui g double `mu' = 1/(1+exp(-`eta')) qui g double `dmudeta' = `mu'*(1-`mu') qui g double `v' = `mu'*(1-`mu') } qui g double `w' = `dmudeta'^2 / `v' // weight for IWLS mata: W=X=. mata: st_view(X,.,"`rhs'") mata: X = X, J(rows(X), 1, 1) mata: st_view(W,.,"`w'") mata: Q = diagonal( X * invsym( cross(X,W,X) ) * X' ) // Q is the diagonal of the matrix Q = X (X'WX) X' in McCullagh & Nelder getmata `qi' = Q qui g double `hi' = `qi'*`w' // H = W^{1/2} X (X'WX)^{-1} X' W^{1/2} if "`model'"=="probit" { // pseudo-responses for probit qui g double `ystar' = `lhs' - `hi'*`v'*`eta'/(2*`dmudeta') } if "`model'"=="cloglog" { // pseudo-responses for logit qui g double `ystar' = `lhs' + `hi'*`mu' * (1-exp(`eta'))/(2*exp(`eta')) } if "`model'"=="logit" { // pseudo-responses for logit qui g double `ystar' = `lhs' + `hi'*(1/2-`mu') } qui g double `z' = `eta' + (`ystar' - `mu') * (1/`dmudeta') // dep. var. for IWLS qui reg `z' `rhs' [aweight=`w'] if `touse' , `options' // WLS qui predict `xb' if `touse' , xb mat `VAL' = ( e(b)-`bold' )' * ( e(b)-`bold' ) // updating convergence value sca `val' = `VAL'[1,1] qui replace `eta' = `xb' // updating eta=x'b mat `bold' = e(b) // updating betas mat `b' = e(b) // store betas *mata: V = (150/(150-2)):*Q // store VCOV Matrix *getmata `V'=V , replace mat `V' = e(V) // store betas local iter = `iter' + 1 // updating iteration number di in green "Iteration `iter'" in green " tol = " in yellow `val' local converged=1 if `val'<=`tol' | `iter'==`maxiter' { if `iter'==`maxiter' { di in red "Warning: Convergence not achieved." local converged=0 //Convergence achived, store } } if "`model'"=="probit" { //calc loglikelihood values qui g double `logl'= `lhs'*ln(`mu')+(1-`lhs')*ln(1-`mu') } if "`model'"=="cloglog" { qui g double `logl'= `lhs'*ln(`mu')+(1-`lhs')*ln(1-`mu') } if "`model'"=="logit" { qui g double `logl'= `lhs'*ln(`mu')+(1-`lhs')*ln(1-`mu') } qui su `logl' local ll=r(sum) //Store ll-values drop `mu' `dmudeta' `v' `w' `z' `xb' `qi' `hi' `ystar' `logl' } di "" // Example in PPML; display options in gml; di as txt "Biased-reduced `model' glm regression" /* // Estimation name and number of parameters */ _col(51) "No. of obs" _col(67) "=" /* */ _col(69) as res %10.0gc e(N) di "" //add pseudo R^2? di "" di as text "Log-likelihood: " as result e(ll) // Display log-likelihood di "" //add if robust/cluster notification local depn "`lhs'" local N=e(N) ereturn local depvar "`lhs'" ereturn post `b' `V' , depname("`depn'") esample(`touse') ereturn display ereturn scalar converged=`converged' ereturn scalar ll = `ll' ereturn scalar N = `N' ereturn local model "`model'" // set e(cmd) last ereturn local cmd "brglm" // set e(cmd) last end