*! gdxis2 0.2.3 2008-01-27
*   > minor cleanup

//  create x() strings for group comparisons

* DO: create group 0 X rhs at group 1 means and vice versa
* DO: check if variables are in model
* DO: verify that lin squ and cube vars are not in varlist

capture program drop gdxis2
program define gdxis2, rclass

    version 9

//  CHECK IF GLOBALS ARE DEFINED

    _gdsetcheck2
    local error = r(error)
    if `error'==1 {
        exit
    }

//  DECODE OPTIONS

    syntax [varlist(default=none)]  /// variable in x() list
           [if] [in]                /// select sample for means 0.2.1
        [ ,                         ///
        LINear(varlist)             /// linear terms of quadratic ver 0.1.2
        SQUared(varlist)            /// squared terms
        CUBed(varlist)              /// cubic terms
        svy                         /// use svy means
        NOEsample                   /// do not use esample; use all cases
        Details                     /// show details
        debug                       /// show debugging output
        DIGits(integer 3)           /// rounding digits
        Reset                       /// reset globals and quit
        label(string)               /// label these globals 0.2.1
        ]

    local fmtdigits = `digits'
    local digits = 1/(10^`digits')
    local q "qui "
    if "`debug'"=="debug" {
        local q ""
    }

//  RESET GLOBALS

    if "`reset'"=="reset" {

        macro drop gislabel     // label for call of gdxis.
        macro drop gis          // group variable set to 1
        macro drop gisg0        // group 0 variable set to 1
        macro drop gisg1        // group 1 variable set to 1
        macro drop rhsg0        // rhs vars for group 0
        macro drop rhsg1        // rhs vars for group 1
        macro drop rhsnoint     // rhs variables for in no intereraction model
        macro drop xis          // non-interaction vars set to grand means
        macro drop xisg0        // group 0 interaction vars set to global means
        macro drop xisg0mn0     // group 0 interaction vars set to group 0 means
        macro drop xisg1        // group 1 interaction vars set to global means
        macro drop xisg1mn1     // group 1 interaction vars set to group 0 means
        macro drop xismn0       // non-interaction vars set to group 0 means
        macro drop xismn1       // non-interaction vars set to group 1 means

    }

//  GLOBALS WITH RHS VARIABLES FOR EACH GROUP AND NOINT MODEL

    * gdxis2 0.1.3
    local rhsg1 "$g1var"
    local rhsg0 "$g0var"
    local rhsnoint "$gvar"

//  Turn label into global variable

    global gislabel "" // reset label
    if "`label'"!="" {
        global gislabel "`label'"
    }

//  CHECK QUADRATIC

    * verify if same variables match across options
    local nlin : word count `linear'
    local nsqu : word count `squared'
    local ncub : word count `cubed'
    local nvar : word count `varlist'

    if `nlin'!=0 {

        if `nlin'!=`nsqu' {
            di in red "# of linear and squared variables don't match."
        } // linear
        if `ncub'!=0 {
            if `ncub'!=`nsqu' {
                di in red "# of cubed and squared variables don't match."
            }
        } // cubic

    } // if nlin option was used

//  SAMPLE TO USE

    if "`debug'"=="debug" {
        if "`if'"!="" {
            di "IS IF:>`if'<"
        }
        if "`in'"!="" {
            di "IS IN:>`in'<"
        }
    }
    tempvar sampis
    if "`noesample'"=="noesample" { // don't use e(sample)
        qui gen `sampis' = 1 `if' `in'
    }
    else {
        qui gen `sampis' = e(sample) `if' `in'
    }

//  CREATE XIS LIST

    * locals to hold x() strings
    local xis ""
    local xismn0 ""
    local xismn1 ""
    local xisg0 ""
    local xisg1 ""
    local xisg0mn0 ""
    local xisg1mn1 ""

    * get globals information about groups
    local gvar  "$gvar"     // name of group variable
    local g1var "$g1var"    // name of group 1
    local g0var "$g0var"    // name of group 0

    * create global with x() info for variables defining groups
    global gisg1 "`g1var'=1"
    global gisg0 "`g0var'=1"
    global gis   "`gvar'=1"

//  CREATE X() INFO BY LOOPING THROUGH VARIABLES

    * if no variables, dummy out globals
    if "`varlist'"=="" {

        global xis " "
        global xisg0 " "
        global xisg1 " "
        global xismn0 " "
        global xismn1 " "
        global xisg0mn0 " "
        global xisg1mn1 " "
        exit

    }

    * if variables, create strings setting variables to means
    tempname mn
    local ivar = 0 // version 0.1.2
    local ilinear = 0 // version 0.1.2

    foreach v in `varlist' `linear' { // loop through varlist and linear

        local ++ivar // version 0.1.2

        * grand non-svy means
        if "`svy'"=="" {
            `q' sum `v' if `sampis'
            local grandmn = r(mean)
        }

        * grand svy means
        else {
            `q' svy: mean `v' if `sampis'
            mat `mn' = e(b)
            local grandmn = `mn'[1,1]
        }

        * 2008-01-25 add rounding for numbers used in strings
        local fmt "%11.`fmtdigits'f"
        local grandmn = string(`grandmn',"`fmt'")

        * within group means
        foreach g in 0 1 { // loop over groups

            * group non-svy mean
            if "`svy'"=="" {
                `q' sum `v' if `sampis' & `gvar'==`g'
                local group`g'mn = r(mean)
            }

            * group svy means
            else {
                `q' svy: mean `v' if `sampis' & `gvar'==`g' // by group
                mat `mn' = e(b)
                local group`g'mn = `mn'[1,1]
            }

            * round the means
            * 2008-01-25 add rounding for numbers used in strings
            local group`g'mn = string(`group`g'mn',"`fmt'")
            * local group`g'mn = round(`group`g'mn',`digits')

        } // foreach g loop

        * x() non-interaction model with grand mean
        local xis "`xis' `v'=`grandmn'"
        * gdxis2 0.1.3 - add to vars in no int model
        local rhsnoint "`rhsnoint' `v'"
        * non-interaction model using group 0 means
        local xismn0 "`xismn0' `v'=`group0mn'"
        * non-interaction model using group 1 means
        local xismn1 "`xismn1' `v'=`group1mn'"

        foreach g in 0 1 {

            * prefix for group g interaction variables
            local nm "`g`g'var'"
            * use grand means with interactions
            local xisg`g' "`xisg`g'' `nm'`v'=`grandmn'"
            * use group means with interactions
            local xisg`g'mn`g' "`xisg`g'mn`g'' `nm'`v'=`group`g'mn'"
            * gdxis2 0.1.3 - add to vars in int model
            local newvarnm "`g`g'var'`v'"
            local rhsg`g' "`rhsg`g'' `newvarnm'"

        }

        * version 0.1.2
        * logic is, if var # is gt # of variables in varlist
        * it must be a quadratic term
        if `ivar'>`nvar' { // if current var is from linear list

            local ++ilinear // which linear term is it?

            if `nsqu'>0 { // there are squared term

                local vsq : word `ilinear' of `squared' // squared var nm
                local grandmn2 = `grandmn'*`grandmn'
                local group0mn2 = `group0mn'*`group0mn'
                local group1mn2 = `group1mn'*`group1mn'
                * x() non-interaction model with grand mean
                local xis "`xis' `vsq'=`grandmn2'"
                * non-interaction model using group 0 means
                local xismn0 "`xismn0' `vsq'=`group0mn2'"
                * non-interaction model using group 1 means
                local xismn1 "`xismn1' `vsq'=`group1mn2'"
                * gdxis2 0.1.5
                local rhsnoint "`rhsnoint' `vsq'"

                foreach g in 0 1 {
                    * prefix for group g interaction variables
                    local nm "`g`g'var'"
                    * use grand means with interactions
                    local xisg`g' "`xisg`g'' `nm'`vsq'=`grandmn2'"
                    * use group means with interactions
                    local xisg`g'mn`g' "`xisg`g'mn`g'' `nm'`vsq'=`group`g'mn2'"
                    * 0.1.5
                    local newvarnm "`g`g'var'`vsq'"
                    local rhsg`g' "`rhsg`g'' `newvarnm'"

                }

            } // squared

            if `ncub'>0 { // there are cubed terms
                local vcu : word `ilinear' of `cubed' // name of squared var
                local grandmn3 = `grandmn'*`grandmn'*`grandmn'
                local group0mn3 = `group0mn'*`group0mn'*`group0mn'
                local group1mn3 = `group1mn'*`group1mn'*`group1mn'
                * x() non-interaction model with grand mean
                local xis "`xis' `vcu'=`grandmn3'"
                * non-interaction model using group 0 means
                local xismn0 "`xismn0' `vcu'=`group0mn3'"
                * non-interaction model using group 1 means
                local xismn1 "`xismn1' `vcu'=`group1mn3'"
                * gdxis2 0.1.5
                local rhsnoint "`rhsnoint' `vcu'"

                foreach g in 0 1 {
                    * prefix for group g interaction variables
                    local nm "`g`g'var'"
                    * use grand means with interactions
                    local xisg`g' "`xisg`g'' `nm'`vcu'=`grandmn3'"
                    * use group means with interactions
                    local xisg`g'mn`g' "`xisg`g'mn`g'' `nm'`vcu'=`group`g'mn3'"
                    * 0.1.5
                    local newvarnm "`g`g'var'`vcu'"
                    local rhsg`g' "`rhsg`g'' `newvarnm'"
                }

            } // cubed

        } // if variable is from set of quadratic terms

    } // foreach v in varlist + quadratics

//  CREATE GLOBALS WITH X() INFORMATION

    * global means for non interaction variables
    global xis      "`xis'"
    * group means for non interaction variables
    global xismn0   "`xismn0'"
    global xismn1   "`xismn1'"
    * global means for interaction variables
    global xisg0    "`xisg0'"
    global xisg1    "`xisg1'"
    * group means for interaction variables
    global xisg0mn0 "`xisg0mn0'"
    global xisg1mn1 "`xisg1mn1'"
    * gdxis2 0.1.3
    global rhsg1 "`rhsg1'"
    global rhsg0 "`rhsg0'"
    global rhsnoint "`rhsnoint'"

//  DETAILS

    if "`details'"=="details" {

        if "$gislabel"!="" {
            local tmp "$gislabel"
            di _new "Label: `tmp'"
        }
        di _new "Globals for RHS variables without interactions:"
        di _new "    \$xis (grand means):       $xis"
        di      "    \$xismn0 (group 0 means):  $xismn0"
        di      "    \$xismn1 (group 1 means):  $xismn1"
        di _new "Globals for group 0 by RHS interaction variables:"
        di _new "    \$xisg0 (grand means):      $xisg0"
        di      "    \$xisg0mn0 (group 0 means): $xisg0mn0"
        di _new "Globals for group 1 by RHS interaction variables:"
        di _new "    \$xisg1 (grand means):      $xisg1"
        di      "    \$xisg1mn1 (group 1 means): $xisg1mn1"
        if "`if'"!="" | "`in'"!="" {
            di _new "Sample selected by: `if' `in'"
        }
        if "`svy'"!="svy" {
            local tmpsvy "not "
        }
        di _new "svy means are `tmpsvy'being used."
        di _new "Variable names:"
        di _new "    \$gvar:        $gvar"
        di      "    \$g0var:       $g0var"
        di      "    \$g1var:       $g1var"
        di      "    \$g0label:     $g0label"
        di      "    \$g1label:     $g1label"
        di _new "RHS variable lists:"
        di _new "    \$rhsg0:       $rhsg0"
        di      "    \$rhsg1:       $rhsg1"
        di      "    \$rhsnoint:    $rhsnoint"
        di _new "RHS group variables set to 1"
        di _new "    \$gis:         $gis"
        di      "    \$gisg0:       $gisg0"
        di      "    \$gisg1:       $gisg1"
    }

end
exit

//  History

* gdxis1 0.1.0 2007-03-11
* gdxis1 0.1.1 2007-03-12 > Allow no rhs variables.
* gdxis1 0.1.2 2007-03-12 > Add quadratic terms.
* gdxis1 0.1.3 2007-03-14 > Add global for rhs of model.
* gdxis1 0.1.4 2007-03-14 > General rename and code cleanup.
* gdxis1 0.1.5 2007-03-15 > Add quad to rhs globals.
* gdxis2 0.2.0 2007-03-22 >
* gdxis2 0.2.1 2007-03-25 > add if
* gdxis2 0.2.2 2008-01-25 > get rounding? and improve output details