*! version 1.8.5 3/25/2001

capture program drop prvalue1
program define prvalue1, rclass
    version 6
    tempname tobase tobase2 temp values probs xb xb_hi xb_lo
    tempname xb_prev xb_dif stdp p0 p1 p0_hi p1_hi p0_lo p1_lo p1_hi p0_dif
    tempname p1_dif p0_prev p1_prev p_prev p_dif mu mu_hi mu_lo mu_prev
    tempname mu_dif always0 a0_prev a0_dif

*=> classify each valid type of model
    if "`e(cmd)'"=="cloglog"  { local io = "typical binary" }
    if "`e(cmd)'"=="cnreg"    { local io = "typical tobit" }
    if "`e(cmd)'"=="fit"      { local io = "typical regress" }
    if "`e(cmd)'"=="gologit"  { local io = "typical mlogit" }
    if "`e(cmd)'"=="intreg"   { local io = "typical tobit" }
    if "`e(cmd)'"=="logistic" { local io = "typical binary" }
    if "`e(cmd)'"=="logit"    { local io = "typical binary" }
    if "`e(cmd)'"=="mlogit"   { local io = "typical mlogit" }
    if "`e(cmd)'"=="nbreg"    { local io = "typical count" }
    if "`e(cmd)'"=="ologit"   { local io = "typical ordered" }
    if "`e(cmd)'"=="oprobit"  { local io = "typical ordered" }
    if "`e(cmd)'"=="poisson"  { local io = "typical count" }
    if "`e(cmd)'"=="probit"   { local io = "typical binary" }
    if "`e(cmd)'"=="regress"  { local io = "typical regress" }
    if "`e(cmd)'"=="tobit"    { local io = "typical tobit" }
    if "`e(cmd)'"=="zinb"     { local io = "twoeq count" }
    if "`e(cmd)'"=="zip"      { local io = "twoeq count" }
    if "`io'"=="" {
        di
        di in y "prvalue1" in r /*
        */ " does not work for the last type of model estimated."
        exit
    }
    local input : word 1 of `io'   /* input routine to _pepred */
    local output : word 2 of `io'  /* output routine */

*=> get info about variables
    if "`output'" != "regress" & "`output'" != "tobit" {
        _pecats
        local ncats = r(numcats)
        local catnms8 `r(catnms8)'
        local catvals `r(catvals)'
        local catnms `r(catnms)'
    }

*=> decode specified input
    syntax [if] [in] [, x(passthru) Rest(passthru) LEvel(passthru) /*
    */ MAXcnt(passthru) noLAbel noBAse Brief Save Diff all YStar]

    * use _pebase to set base values
    _pebase `if' `in' , `x' `rest' `choices' `all'
    mat `tobase' = r(pebase)
    if "`input'"=="twoeq" { mat `tobase2' = r(pebase2) }

*=> if user wants to compare two models, make sure ok to do so
    if "`diff'"=="diff" {
        if "$PRVcmd" != "`e(cmd)'" {
            di in r "saved results not estimated with `e(cmd)'"
            exit 198
        }
        if "$PRVdepv" != "`e(depvar)'" {
            di in r "saved results not estimated with depvar `e(depvar)'"
            exit 198
        }
        if "`output'"=="ordered" | "`output'"=="mlogit" {
            if "`catvals'"!="$PRVvals" {
            di in r "category values for saved and current " /*
            */ "`e(depvar)' do not match"
            exit 198
            }
        }
    }

 *=> build PE_in matrix
    if "`input'"=="typical" {
        mat PE_in = `tobase'
    }
    if "`input'"=="twoeq" {
        mat PE_in = `tobase'
        mat PE_in2 = `tobase2'
    }
    _pepred, `level' `maxcnt'
    * get level (ci) and maxcount info
    local level = `r(level)' * 100
    local max_i = r(maxcount)

    if "`brief'"=="" {
        di " "
        if "`diff'"=="" {
            di in y "`e(cmd)'" in g ": Predictions for " in y "`e(depvar)'"
        }
        if "`diff'"=="diff" {
            di in y "`e(cmd)'" in g ": Change in Predictions for  " /*
            */ in y "`e(depvar)'"
        }
    }

*=> REGRESS AND TOBIT ROUTINES

    if "`output'" == "tobit" | "`output'" == "regress" {
        * get results from _pepred
        mat `temp' = r(xb)
        sca `xb' = `temp'[1,1]
        mat `temp' = r(xb_lo)
        sca `xb_lo' = `temp'[1,1]
        mat `temp' = r(xb_hi)
        sca `xb_hi' = `temp'[1,1]
        mat `temp' = r(stdp)
        sca `stdp' = `temp'[1,1]

        if "`output'"=="regress" {
            di _n in g "Predicted value of y: " in y %9.0g `xb' in g /*
            */ _skip(3) "`level'% ci: (" in y %9.0g `xb_lo' in g "," /*
            */ in y %9.0g `xb_hi' in g ")"
            if "`diff'"=="diff" {
                sca `xb_prev' = _PRVsav[1,1]
                di _n _col(2) in g "Saved value of yHat: " in y %9.0g /*
                */ `xb_prev'
                di _col(11) in g "Difference: " in y %9.0g `xb'-`xb_prev'
            }
        }
        if "`output'"=="tobit" {
        di _n in g "Predicted value of y*: " in y %9.0g `xb' in g /*
        */ _skip(3) "`level'% ci: (" in y %9.0g `xb_lo' in g "," /*
        */ in y %9.0g `xb_hi' in g ")"
            if "`diff'"=="diff" {
                sca `xb_prev' = _PRVsav[1,1]
                di _n _col(5) in g "Saved value of y*: " in y %9.0g `xb_prev'
                di _col(12) in g "Difference: " in y %9.0g `xb'-`xb_prev'
            }
        }

        *save results if option specified
        if "`save'"=="`save'" {
            mat _PRVsav = `xb', `stdp'
            mat colnames _PRVsav = xb stdp
        }

        *return xb and level in r()
        return scalar xb = `xb'
        return scalar xb_lo = `xb_lo'
        return scalar xb_hi = `xb_hi'
        return local level `level'
    }

*=> Binary output

    if "`output'" == "binary" {

        mat `temp' = r(xb)
        sca `xb' = `temp'[1,1]
        mat `temp' = r(xb_lo)
        sca `xb_lo' = `temp'[1,1]
        mat `temp' = r(xb_hi)
        sca `xb_hi' = `temp'[1,1]
        mat `temp' = r(stdp)
        sca `stdp' = `temp'[1,1]
        di ""
            if "`diff'"=="diff" {
                di in g _col(22) "Current" _col(36) /*
                */ "Saved" _col(43) "Difference"
            }

        if "`brief'"=="" {
            if "`ystar'"=="ystar" {
                if "`diff'"=="" {
                    di in g "  y*: " in y %7.4f _col(22) /*
                    */ `xb' _col(32) in g "`level'% ci: (" in y %7.4f /*
                    */ `xb_lo' in g "," in y %7.4f `xb_hi' in g ")"
                }
                else { /* difference */
                    sca `xb_prev' = _PRVsav[1,1]
                    sca `xb_dif' = `xb' - `xb_prev'
                    di _n in g "  y*:" in y %7.4f _col(22) `xb' /*
                    */ %7.4f _col(34) `xb_prev' %7.4f _col(46) `xb_dif'
                }
            }
        }

        * return xb
        return scalar xb = `xb'
        return scalar xb_lo = `xb_lo'
        return scalar xb_hi = `xb_hi'
        return local level `level'

        * get _pepred results
        mat `temp' = r(p0)
        sca `p0' = `temp'[1,1]
        mat `temp' = r(p1)
        sca `p1' = `temp'[1,1]
        mat `temp' = r(p0_hi)
        sca `p0_hi' = `temp'[1,1]
        mat `temp' = r(p1_hi)
        sca `p1_hi' = `temp'[1,1]
        mat `temp' = r(p0_lo)
        sca `p0_lo' = `temp'[1,1]
        mat `temp' = r(p1_lo)
        sca `p1_lo' = `temp'[1,1]

        * get labels of binary categories
        if "`label'"!="nolabel" { local p0lab : word 1 of `catnms8' }
        else { local p0lab : word 1 of `catvals' }
        if "`label'"!="nolabel" { local p1lab : word 2 of `catnms8' }
        else { local p1lab : word 2 of `catvals' }

        if "`diff'" == "" {
            di in g "  Pr(y=`p1lab'|x):" _col(22) in y %7.4f `p1' /*
            */ _col(32) in g "`level'% ci: (" in y %6.4f `p1_lo' /*
            */ in g "," in y %6.4f `p1_hi' in g ")"
            di in g "  Pr(y=`p0lab'|x):" _col(22) in y %7.4f `p0' /*
            */ _col(32) in g "`level'% ci: (" in y %6.4f `p0_hi' /*
            */ in g "," in y %6.4f `p0_lo' in g ")"
        }
        else { /* difference */
            sca `p1_prev' = _PRVsav[1, 3]
            sca `p0_prev' = 1 - `p1_prev'
            sca `p1_dif' = `p1' - `p1_prev'
            sca `p0_dif' = `p0' - `p0_prev'
            di in g "  Pr(y=`p1lab'|x):" in y %7.4f _col(22) `p1' /*
            */ %7.4f _col(34) `p1_prev' %7.4f _col(46) `p1_dif'
            di in g "  Pr(y=`p0lab'|x):" in y %7.4f _col(22) `p0' /*
            */ %7.4f _col(34) `p0_prev' %7.4f _col(46) `p0_dif'
        }

        if "`save'"=="save" {
            mat _PRVsav = `xb', `stdp', `p1'
            mat colnames _PRVsav = xb stdp p1
        }

        * return probabilities in r()
        return scalar p0 = `p0'
        return scalar p1 = `p1'
        return scalar p0_hi = `p0_hi'
        return scalar p0_lo = `p0_lo'
        return scalar p1_hi = `p1_hi'
        return scalar p1_lo = `p1_lo'
    }

*=> Ordinal Outcomes

    if "`output'" == "ordered" {
        * get xb from _pepred
        mat `temp' = r(xb)
        sca `xb' = `temp'[1,1]
        mat `temp' = r(xb_lo)
        sca `xb_lo' = `temp'[1,1]
        mat `temp' = r(xb_hi)
        sca `xb_hi' = `temp'[1,1]
        mat `temp' = r(stdp)
        sca `stdp' = `temp'[1,1]
        *predict index as output
        di ""
        if "`diff'"=="diff" {
            di in g _col(22) "Current" _col(36) /*
            */ "Saved" _col(43) "Difference"
        } /* dif */
       if "`ystar'"=="ystar" {
            if "`diff'"=="" {
                di in g "  y*: " in y %7.4f _col(22) /*
                */ `xb' _col(32) in g "`level'% ci: (" in y %7.4f /*
                */ `xb_lo' in g "," in y %7.4f `xb_hi' in g ")"
            }
            else { /* difference */
                sca `xb_prev' = _PRVsav[1,1]
                sca `xb_dif' = `xb' - `xb_prev'
                di in g "  y*:" in y %7.4f _col(22) `xb' /*
                */ %7.4f _col(34) `xb_prev' %7.4f _col(46) `xb_dif'
            }
        }
        * return xb
        return scalar xb = `xb'
        return scalar xb_lo = `xb_lo'
        return scalar xb_hi = `xb_hi'
        return local level `level'

        * cycle though categories
        local i = 1
        while `i' <= `ncats' {
            local p`i'val : word `i' of `catvals'
            * values matrix contains actual category values from ologit
            mat `values' = nullmat(`values') \ `p`i'val'
            local p`i'lab : word `i' of `catnms8'
            local labdisp "`p`i'val'"
            if "`label'"!="nolabel" { local labdisp "`p`i'lab'" }
            * get probability
            tempname p`i'
            mat `temp' = r(p`i')
            sca `p`i'' = `temp'[1, 1]
            mat `probs' = nullmat(`probs') \ `p`i''

            if "`diff'"=="" {
                di in g "  Pr(y=`labdisp'|x):" _col(22) in y %7.4f `p`i''
            }
            if "`diff'"=="diff" {
                sca `p_prev' = _PRVp[`i', 1]
                sca `p_dif' = `p`i''-`p_prev'
                di in g "  Pr(y=`labdisp'|x): " _col(22) in y %7.4f /*
                */ `p`i'' _col(34) %7.4f `p_prev' _col(46) %7.4f `p_dif'
            }
            local i = `i' + 1
        }

        *save values (save has to come before return because return destroys matrices!)
        if "`save'"=="save" {
            mat _PRVsav = `xb', `stdp'
            mat colnames _PRVsav = xb stdp
            global PRVvals = "`catvals'"
            mat _PRVp = `probs'
        }
        *return probabilities and category values in r()
        return matrix values `values'
        return matrix probs `probs'

    } /* if "`output'" == "ordered" */

*=> Nominal Outcomes

    if "`output'" == "mlogit" {

        *print headings
        di _n in g "Predicted probabilities for each category:"
        if "`diff'"=="diff" {
            di _n in g _col(22) "Current" _col(36) /*
            */ "Saved" _col(43) "Difference"
        }

        *cycle through each category
        local i = 1
        while `i' <= `ncats' {
            *get actual category value
            local p`i'val : word `i' of `catvals'
            mat `values' = nullmat(`values') \ `p`i'val'

            *get label
            local p`i'lab : word `i' of `catnms8'
            local labdisp "`p`i'val'"
            if "`label'"!="nolabel" { local labdisp "`p`i'lab'" }

            *get probability computed by _pepred and stored in r()
            tempname p`i'
            mat `temp' = r(p`i')
            sca `p`i'' = `temp'[1, 1]
            mat `probs' = nullmat(`probs') \ `p`i''

            *display output
            if "`diff'"=="" {
                di in g "  Pr(y=`labdisp'|x): " _col(22) in y %7.4f `p`i''
            }
            if "`diff'"=="diff" {
                sca `p_prev' = _PRVp[`i', 1]
                sca `p_dif' = `p`i''-`p_prev'
                di in g "  Pr(y=`labdisp'|x): " _col(22) /*
                */ in y %7.4f `p`i'' _col(34) %7.4f `p_prev' /*
                */ _col(46) %7.4f `p_dif'
            }
            local i = `i' + 1
        }

        *save results
        if "`save'"=="save" {
            global PRVvals = "`catvals'"
            mat _PRVp = `probs'
        }
        *return results
        return matrix values `values'
        return matrix probs `probs'

    } /* if "`output'" == "mlogit" */

*=> Count Outcomes

    if "`output'" == "count" {

        *return selected level in r()
        return local level `level'

        *get mu and stdp
        mat `temp' = r(mu)
        sca `mu' = `temp'[1,1]
        mat `temp' = r(stdp)
        sca `stdp' = `temp'[1,1]

        *output for mu
        di _n in g "Predicted rate: " in y %-7.3g `mu' _c

        *return mu in r()
        return scalar mu = `mu'

        *upper and lower ci for mu if poisson
        if "`e(cmd)'"=="poisson" {
            mat `temp' = r(mu_lo)
            sca `mu_lo' = `temp'[1,1]
            mat `temp' = r(mu_hi)
            sca `mu_hi' = `temp'[1,1]
            if "`brief'"=="" {
                di in g _c _col(3) /*
                */ "`level'% CI [" in y %-7.3g `mu_lo' /*
                */ in g "," in y %7.3g `mu_hi' in g "]" _n
            }
            return scalar mu_lo = `mu_lo'
            return scalar mu_hi = `mu_hi'
            return local level `level'
        }

        *display previous mu if dif option on
        if "`diff'"=="diff" {
            sca `mu_prev' = _PRVsav[1,1]
            sca `mu_dif' = `mu' - `mu_prev'
            di in g _col(10) "Saved: " %-7.3g in y `mu_prev'
            di in g _col(5) "Difference: " %-7.3g in y `mu_dif'
        }

        *print header
        di _n in g "Predicted probabilities:" _n
        *for counts 0-`max_i':"
        if "`diff'"=="diff" {
            di in g _col(22) "Current" _col(36) "Saved" /*
            */ _col(43) "Difference"
        }

        *cycle from 0 to maximum desired count
        local i = 0
        local isodd = 0
        while `i' <= `max_i' {
            local isodd = abs(`isodd' - 1)
            mat `values' = nullmat(`values') \ `i'
            tempname p`i' p_lo`i' p_hi`i' lo hi
            mat `temp' = r(p`i')
            sca `p`i'' = `temp'[1, 1]
            mat `probs' = nullmat(`probs') \ `p`i''
            if "`diff'"=="" {
                local lf ""
                if `isodd' { local lf "_c" }
                if "`input'"=="twoeq" & `i'==0 { /* zip or zinb @ 0 */
                    di in g `lf'"  Pr(y=`i'|x,z): " in y %6.4f `p`i''
                }
                else {
                    di in g `lf'"  Pr(y=`i'|x):   " in y %6.4f `p`i''
                } /* zip zinb */
            }
            else {
                sca `p_prev' = _PRVp[`i'+1, 1]
                sca `p_dif' = `p`i''-`p_prev'
                if "`input'"=="twoeq" & `i'==0 { /* zip or zinb @ 0 */
                    di in g "  Pr(y=`i'|x,z): " _col(22) in y /*
                    */ %7.4f `p`i'' _col(34) %7.4f `p_prev' /*
                    */ _col(46) %7.4f `p_dif'
                }
                else {
                    di in g "  Pr(y=`i'|x):   " _col(22) in y /*
                    */ %7.4f `p`i'' _col(34) %7.4f `p_prev' /*
                    */ _col(46) %7.4f `p_dif'
                }
            }
            local i = `i' + 1
        }

        * display inflate probability if ZIP or ZINB
        if "`input'"=="twoeq" {
            mat `temp' = r(always0)
            sca `always0' = `temp'[1, 1]
            if "`diff'"=="diff" {
                sca `a0_prev' = _PRVsav[1, 3]
                sca `a0_dif' = `always0' - `a0_prev'
                di _n in g "Pr(Always0|z): " _col(22) /*
                */ in y %7.4f `always0' _col(34) in y %7.4f `a0_prev' /*
                */ _col(46) %7.4f `a0_dif'
            }
            else {
                di _n in g "Pr(Always0|z):" in y %7.4f `always0'
            }
            *return always0 in r()
            return scalar always0 = `always0'
        }

        *save values if save option specified
        if "`save'"=="save" {
            mat _PRVsav = `mu', `stdp'
            mat colnames _PRVsav = mu stdp
            if "`input'"=="twoeq" {
                mat _PRVsav = `mu', `stdp', `always0'
                mat colnames _PRVsav = mu stdp always0
            }
            mat _PRVp = `probs'
        }

        *return values and probabilities in r()
        return matrix values `values'
        return matrix probs `probs'

    } /* if "`output'" == "count" */

*=> Common to all types of models

    * print base values
    if "`brief'"=="" & "`base'"!="nobase" {
        if "`input'"=="twoeq" { di _n in g "x values for count equation" }
        mat rownames `tobase' = "x="
        if "`diff'"=="" {
            mat _PEtemp = `tobase'
            _peabbv _PEtemp
            mat list _PEtemp, noheader
        }
        else {
            local tmp1: colnames `tobase'
            local tmp2: colnames PRVbase
            if "`tmp1'"=="`tmp2'" & length("`tmp1'") < 80 {
                mat _PEtemp = (`tobase' \ PRVbase \ (`tobase' - PRVbase))
                mat rownames _PEtemp = "Current=" "Saved=" "Diff="
                _peabbv _PEtemp
                mat list _PEtemp, noheader
            }
            else {
                mat rownames `tobase' = "Current="
                mat rownames PRVbase =  "  Saved="
                mat _PEtemp = `tobase'
                _peabbv _PEtemp
                mat list _PEtemp, noheader
                mat _PEtemp = PRVbase
                _peabbv _PEtemp
                mat list _PEtemp, noheader
            }
        }

        * print base values of binary equation
        if "`input'"=="twoeq" {
            di _n in g "z values for binary equation"
            mat rownames `tobase2' = "z="
            if "`diff'"=="" {
                mat _PEtemp = `tobase2'
                _peabbv _PEtemp
                mat list _PEtemp, noheader
            }
            else {
                local tmp1: colnames `tobase2'
                local tmp2: colnames PRVbase2
                if "`tmp1'"=="`tmp2'"  & length("`tmp1'") < 80 {
                    mat `temp' = (`tobase2' \ PRVbase2 \ (`tobase2' - PRVbase2))
                    mat rownames `temp' = "Current=" "Saved=" "Diff="
                    mat _PEtemp = `temp'
                    _peabbv _PEtemp
                    mat list _PEtemp, noheader
                }
                else {
                    mat rownames `tobase2' = "Current="
                    mat rownames PRVbase2 = "  Saved="
                    mat _PEtemp = `tobase2'
                    _peabbv _PEtemp
                    mat list _PEtemp, noheader
                    mat _PEtemp = PRVbase2
                    _peabbv _PEtemp
                    mat list _PEtemp, noheader
                }
            }
        } /* twoeq */
    }

    *save command name and dependent variable name
    if "`save'"=="save" {
        global PRVcmd = "`e(cmd)'"
        global PRVdepv = "`e(depvar)'"
        mat PRVbase = `tobase'
        mat rownames PRVbase = "saved="
        if "`input'"=="twoeq" {
            mat PRVbase2 = `tobase2'
            mat rownames PRVbase2 = "saved x"
        }
    }

    return mat x `tobase'
    if "`input'"=="twoeq" {
        return mat x2 `tobase2'
    }

end