Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Reporting Odds Ratios Using Collect

    I would like to report odds-ratios instead of coefficients in a regression table I am creating using collect after running regression models using stcox and xtstreg. Before, I would use esttab ..., eform to accomplish this. However, I would like to take advantage of the customization available using the collect command.

    I have included code that should reproduce the incomplete table I currently see.

    I have two secondary questions on how to use collect as well:
    I would like to report interactions without showing the variable values in the variables labels. For example, using the code below, I would like the output to display "Green" instead of "Green=1" in the left column.
    Finally, I would like to add rows at the bottom of the regression table as follows: One line with just "Fixed effects" written in the left column, a row indicating whether firm fixed effects are used, a row for the number of observations, a row for the number of failures, and a row for the log likelihood.

    I realize these three questions are distinct, and I appreciate your help on any of the three issues.

    Code:
    * Create dataset of 100 observations
    drop _all
    set obs 100
    * Set seed for reproducability
    set seed 101
    
    * Generate person-ID
    g person_id = _n
    * Generate individual-level covariates
    g x1 = round(runiform(0,1))
    g x2 = round(runiform(0,1))
    g x3 = rnormal()
    
    * Label variables
    label var x1 "Red"
    label var x2 "Blue"
    label var x3 "Green"
    
    * Generate firm ID variable
    g firm_id = round(runiform(0,10))
    
    * Generate linear predictor using covariates and firm effect
    g lp = 0.5 * x1 - 0.3 * x2 + 0.2 * firm_id
    
    * Generate baseline hazard and survival times based on exponential distribution
    g hazard = exp(lp)
    g uncensored_survival = -ln(runiform()) / hazard
    
    * Randomly censor up to 20% of the observations
    g random_censor = runiform()
    g survival = uncensored_survival
    qui sum uncensored_survival
    replace survival = min(uncensored_survival, runiform(0,`r(mean)')) if random_censor<0.2
    g failure_observed = 1
    replace failure_observed = 0 if survival<uncensored_survival
    
    * stset and xtset the data
    stset survival, failure(failure_observed)
    xtset firm_id
    
    * Run survival analysis and collect results
    * No firm fixed effect
    collect clear
    collect _r_b _r_z fe_label=" " firm_fe="No", tag(model[(1)]): stcox x1##x2 x3
    * With firm random intercepts
    collect _r_b _r_z firm_fe="Yes", tag(model[(2)]): xtstreg x1##x2 x3, distribution(exponential)
    
    * Collect results into a nice table
    collect layout (colname[x1##x2 x3]#result) (model)
    * Format table
    collect style showbase off
    collect style cell, nformat(%5.2f)
    collect style cell border_block, border(right, pattern(nil))
    collect style cell result[_r_z], sformat("(%s)") margin(bottom, width(3pt))
    collect style cell result[N N_fail ll], nformat(%15.0fc)
    collect style cell cell_type[item column-header], halign(center)
    collect style header result, level(hide)
    collect style column, extraspace(0) // No extra rows between coefficients
    * Remove base values of interactions from table
    collect style showbase off // Removes non-coefficient base terms for indicator variables and interactions
    collect style row stack, spacer delimiter(" x ") // This adds "x" as the delimited in interaction terms
    * Show rows at the bottom of the table for firm fixed effects, observations, failures observed, and log likelihood
    collect label levels result fe_label "Fixed Effects" firm_fe "Firm" N "Observations" N_fail "Failures" ll "Log likelihood", replace
    collect style header result[fe_label firm_fe N N_fail ll], level(label)
    collect preview
    
    * Why won't firm fixed effects show up?
    collect levelsof result // Shows that all of these are present: fe_label firm_fe N N_fail ll
    Last edited by Nathan Barrymore; 10 Sep 2024, 10:42.

  • #2
    For reference, this is the output that I see.

    Code:
    . collect preview
    
    ------------------------------
                     (1)     (2)  
    ------------------------------
    Red=1            0.82    0.92 
                   (-0.61) (-0.23)
                                  
    Blue=1           0.46    0.47 
                   (-2.31) (-2.25)
                                  
    Red=1 x Blue=1   1.93    1.71 
                    (1.47)  (1.14)
                                  
    Green            0.98    0.99 
                   (-0.19) (-0.05)
    ------------------------------

    Comment


    • #3
      The default with collect style header with option -level()- is to show labels corresponding to the levels of the categorical variable. You just need to label these levels as desired. To show the stats, add this to the table's layout.

      Code:
      * Create dataset of 100 observations
      drop _all
      set obs 100
      * Set seed for reproducability
      set seed 101
      
      * Generate person-ID
      g person_id = _n
      * Generate individual-level covariates
      g x1 = round(runiform(0,1))
      g x2 = round(runiform(0,1))
      g x3 = rnormal()
      
      * Label variables
      label var x1 "Red"
      label var x2 "Blue"
      label var x3 "Green"
      
      * Generate firm ID variable
      g firm_id = round(runiform(0,10))
      
      * Generate linear predictor using covariates and firm effect
      g lp = 0.5 * x1 - 0.3 * x2 + 0.2 * firm_id
      
      * Generate baseline hazard and survival times based on exponential distribution
      g hazard = exp(lp)
      g uncensored_survival = -ln(runiform()) / hazard
      
      * Randomly censor up to 20% of the observations
      g random_censor = runiform()
      g survival = uncensored_survival
      qui sum uncensored_survival
      replace survival = min(uncensored_survival, runiform(0,`r(mean)')) if random_censor<0.2
      g failure_observed = 1
      replace failure_observed = 0 if survival<uncensored_survival
      
      * stset and xtset the data
      stset survival, failure(failure_observed)
      xtset firm_id
      
      * Run survival analysis and collect results
      * No firm fixed effect
      collect clear
      collect _r_b _r_z fe_label=" " firm_fe="No", tag(model[(1)]): stcox x1##x2 x3
      * With firm random intercepts
      collect _r_b _r_z firm_fe="Yes", tag(model[(2)]): xtstreg x1##x2 x3, distribution(exponential)
      
      * Collect results into a nice table
      collect layout (colname[x1##x2 x3]#result) (model) 
      * Format table
      collect style showbase off
      collect style cell, nformat(%5.2f)
      collect style cell border_block, border(right, pattern(nil))
      collect style cell result[_r_z], sformat("(%s)") margin(bottom, width(3pt))
      collect style cell result[N N_fail ll], nformat(%15.0fc)
      collect style cell cell_type[item column-header], halign(center)
      collect style header result, level(hide)
      collect style column, extraspace(0) // No extra rows between coefficients
      * Remove base values of interactions from table
      collect style showbase off // Removes non-coefficient base terms for indicator variables and interactions
      collect style row stack, spacer delimiter(" x ") // This adds "x" as the delimited in interaction terms
      * Show rows at the bottom of the table for firm fixed effects, observations, failures observed, and log likelihood
      collect label levels result fe_label "Fixed Effects" firm_fe "Firm" N "Observations" N_fail "Failures" ll "Log likelihood", replace
      collect style header result[fe_label firm_fe N N_fail ll], level(label)
      collect label levels  x1 1 "Red" 
      collect label levels  x2 1 "Blue" 
      collect preview
      collect layout (colname[x1##x2 x3]#result result[fe_label firm_fe N N_fail ll]) (model)
      Res.:

      Code:
      . collect layout (colname[x1##x2 x3]#result result[fe_label firm_fe N N_fail ll]) (model)
      
      Collection: default
            Rows: colname[x1##x2 x3]#result result[fe_label firm_fe N N_fail ll]
         Columns: model
         Table 1: 21 x 2
      
      ------------------------------
                       (1)     (2)  
      ------------------------------
      Red              0.82    0.92 
                     (-0.61) (-0.23)
                                    
      Blue             0.46    0.47 
                     (-2.31) (-2.25)
                                    
      Red x Blue       1.93    1.71 
                      (1.47)  (1.14)
                                    
      Green            0.98    0.99 
                     (-0.19) (-0.05)
                                    
      Fixed Effects                 
                                    
      Firm              No     Yes  
                                    
      Observations     100     100  
                                    
      Failures          85          
                                    
      Log likelihood   -297     9   
      ------------------------------

      Comment


      • #4
        Thank you very much Andrew!

        A follow up question. In the table you produced, the "Failures" value is empty for model 2 in the table. I believe this is because the command xtstreg does not store N_fail. I would like to manually add this to the collection after running that command. I would like to do something like the code below, though it causes an error as follows:

        Code:
        * With firm fixed effect
        collect _r_b _r_z firm_fe="Yes", tag(model[(2)]): xtstreg x1##x2 x3, distribution(exponential)
        
        * Without the command below, "Failures" is not populated for model 2
        * With the command below, "Failures" does populate, but "Observations" does not populate for model 2
        collect N_fail=r(N), tag(model[(2)]): count if failure_observed==1 & e(sample)

        Comment


        • #5
          If you want to insert the value manually, you can use collect get.

          Code:
          * Create dataset of 100 observations
          drop _all
          set obs 100
          * Set seed for reproducability
          set seed 101
          
          * Generate person-ID
          g person_id = _n
          * Generate individual-level covariates
          g x1 = round(runiform(0,1))
          g x2 = round(runiform(0,1))
          g x3 = rnormal()
          
          * Label variables
          label var x1 "Red"
          label var x2 "Blue"
          label var x3 "Green"
          
          * Generate firm ID variable
          g firm_id = round(runiform(0,10))
          
          * Generate linear predictor using covariates and firm effect
          g lp = 0.5 * x1 - 0.3 * x2 + 0.2 * firm_id
          
          * Generate baseline hazard and survival times based on exponential distribution
          g hazard = exp(lp)
          g uncensored_survival = -ln(runiform()) / hazard
          
          * Randomly censor up to 20% of the observations
          g random_censor = runiform()
          g survival = uncensored_survival
          qui sum uncensored_survival
          replace survival = min(uncensored_survival, runiform(0,`r(mean)')) if random_censor<0.2
          g failure_observed = 1
          replace failure_observed = 0 if survival<uncensored_survival
          
          * stset and xtset the data
          stset survival, failure(failure_observed)
          xtset firm_id
          
          * Run survival analysis and collect results
          * No firm fixed effect
          collect clear
          collect _r_b _r_z fe_label=" " firm_fe="No", tag(model[(1)]): stcox x1##x2 x3
          * With firm random intercepts
          collect _r_b _r_z firm_fe="Yes", tag(model[(2)]): xtstreg x1##x2 x3, distribution(exponential)
          
          * Collect results into a nice table
          collect layout (colname[x1##x2 x3]#result) (model) 
          * Format table
          collect style showbase off
          collect style cell, nformat(%5.2f)
          collect style cell border_block, border(right, pattern(nil))
          collect style cell result[_r_z], sformat("(%s)") margin(bottom, width(3pt))
          collect style cell result[N N_fail ll], nformat(%15.0fc)
          collect style cell cell_type[item column-header], halign(center)
          collect style header result, level(hide)
          collect style column, extraspace(0) // No extra rows between coefficients
          * Remove base values of interactions from table
          collect style showbase off // Removes non-coefficient base terms for indicator variables and interactions
          collect style row stack, spacer delimiter(" x ") // This adds "x" as the delimited in interaction terms
          * Show rows at the bottom of the table for firm fixed effects, observations, failures observed, and log likelihood
          collect label levels result fe_label "Fixed Effects" firm_fe "Firm" N "Observations" N_fail "Failures" ll "Log likelihood", replace
          collect style header result[fe_label firm_fe N N_fail ll], level(label)
          collect label levels  x1 1 "Red" 
          collect label levels  x2 1 "Blue" 
          collect preview
          count if failure_observed==1 & e(sample)
          collect get N_fail=r(N), tags(N_fail[] model[(2)])
          collect layout (colname[x1##x2 x3]#result result[fe_label firm_fe N N_fail ll]) (model)
          Res.:

          Code:
          . collect layout (colname[x1##x2 x3]#result result[fe_label firm_fe N N_fail ll]) (model)
          
          Collection: default
                Rows: colname[x1##x2 x3]#result result[fe_label firm_fe N N_fail ll]
             Columns: model
             Table 1: 21 x 2
          
          ------------------------------
                           (1)     (2)  
          ------------------------------
          Red              0.82    0.92 
                         (-0.61) (-0.23)
                                        
          Blue             0.46    0.47 
                         (-2.31) (-2.25)
                                        
          Red x Blue       1.93    1.71 
                          (1.47)  (1.14)
                                        
          Green            0.98    0.99 
                         (-0.19) (-0.05)
                                        
          Fixed Effects                 
                                        
          Firm              No     Yes  
                                        
          Observations     100     100  
                                        
          Failures          85      85  
                                        
          Log likelihood   -297     9   
          ------------------------------

          Comment

          Working...
          X