Announcement

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

  • Alternatives to margins command (too slow)

    Hi,

    I have a simple program that estimates that regresses an outcome on (a) event-time dummies (i.e. dummies for time relative to year in which a particular event happens), (b) age dummies and (c) year dummies. I then estimate margins at the unique values of the event-time variable (e.g., 1 period before event, 2 periods before event,...) that abstract from the effect of the event (i.e., I set the event-dummies to zero; put differently, I consider the effect at the value of the constant). Here is the program:


    Code:
        cap program drop event_study
        program define event_study, rclass    
    
            *** Syntax
                syntax [varlist] [if], [                 ///
                    outcome(string)                  ///
                    time(string)                          ///
                    baselevel(string)                ///                
                    age_F(string)                     ///
                    years(string)]                                    
                    
            *** Regression
                reg     `outcome'                ///
                        ib`baselevel'.`time'    ///
                        i.`age_F'                    ///
                        i.`years', r
                        
            *** Margins
                 margins, over(`time') at(`time' = `baselevel') nose
        end
    The code works well. However, the margins command is incredibly slow. Is this because I use factor variables? Is there an alternative way to estimate the margins faster? Would you do it by hand? I am not sure how to do it in a general form (the program allows for a flexible set of covariates).

    Thank you so much for your help!

  • #2
    You tell us nothing about the size of your dataset - this wouldn't perhaps be the 36,553,056 observations you mentioned in your previous topic?

    Comment


    • #3
      Sorry about that: it varies quite a bit. The lower bound is 1 million obs. The upper bound is around 10 million obs.

      Comment


      • #4
        If someone is interested in the solution. I did the following to calculate the margins:

        Code:
                            local coefs: colnames e(b)                                 
                            local coefs = regexr("`coefs'","..+\\`time'","")           
                            tokenize "`coefs'"                                       
           
                            mat Betas = e(b)                                          
                            mat b = Betas[1, "`1'".. "_cons"]                       
                            local coefs = regexr("`coefs'","_cons","")                
                            mata: b     = st_matrix("b")
                            mata: X     = st_data(. , "`coefs'")
                            mata: rows  = rows(X)
                            mata: cons  = J(rows, 1, 1)
                            mata: X     = X, cons
                            mata: y_hat = X*b'
                            cap drop y_hat
                            mata: st_addvar("float", ("y_hat"))
                            mata: st_store(., "y_hat", y_hat)
                           
                           levelsof `time', local(levels)                         
                           local size: list sizeof local(levels)                 
                           mat Fcounterf_`outcome' = J(`size', 2, .)            
                           local i = 1
                           foreach l of local levels {                                
                              if `sweight' == 1 {                                 
                                        qui sum y_hat [weight=weight] if `time' == `l'       
                              }
                              else {
                                       qui sum y_hat if `time' == `l'                  
                               }
                            
                                mat Fcounterf_`outcome'[`i', 1] = `l'
                                mat Fcounterf_`outcome'[`i', 2] = r(mean)
                                local i = `i'+1        
                                }        
                                
                               mat list Fcounterf_`outcome'

        Comment

        Working...
        X