Announcement

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

  • If Command executed when condition is false

    Hi everyone

    Stata 16
    I run capture regress and have an if-else command to handle errors.
    The data set contains multiple survey years and I want to try to regress each year separately. Most years are fine but in the year 2000 there was no survey so it should enter the if command and skip the else part.
    I've checked the code and it does execute the if part but also enters the else part - wrongly. Ive tried to change the else to if _rc==0 and this still occurs.

    The error is (unsurprisingly):
    _b not allowed when e(b) is not present

    Here's a sample:

    Code:
    forvalues year = 1993/2009 {
         cap reg `q' treat `controls' if survey_year==`year', robust
          
          if _rc!=0 {
                 (handle errors)
                 di "No survey this year"
           }
    
          di _rc
          else {
                local beta = _b[treat]
           }
    }

  • #2
    Unless code for an if condition is followed immediately by code for an else condition, the else condition is ignored. That may seem surprising, but it's true. Indeed you can experiment with this code as the entirety of a do-file or do-file editor window:

    Code:
    else {
        di "42"
    }
    Stata doesn't regard an else condition dissociated from any if condition as an error.

    Further, your line


    Code:
    di _rc 
    will I guess always display 0 as either it follows a regress that worked or it follows a display that worked. .

    See https://www.stata.com/support/faqs/d...-with-foreach/ for more discussion of your context, a loop that might fail. for one or more cases. As a regression can fail for more reasons than one, this code might fit your situation better:


    Code:
    forvalues year = 1993/2009 {
        quietly count if survey_year == `year'
        if r(N) == 0 di "No survey in `year'"
        else cap reg `q' treat `controls' if survey_year==`year', robust
          
        if _rc != 0 di _rc
        else local beta = _b[treat]
        * do something with that
    }
    If all you want is one coefficient from each regression, statsby cuts out the need for your own loop.

    Comment


    • #3
      Hi Nick,

      Thanks for the response (and for many many others I've read).
      I re-read the FAQ you provided and it didn't solve my problem.

      I tried to change the else command to if _rc==0 and the problem remains.
      Stata enters that part of the code when it shouldn't - when di _rc displays 2000.

      I wonder what you mean by "followed immediately" - isn't that the case in the sample I added? (same as in the original code).

      Lastly, both the if and the else clauses have more in them then what showed in the sample: there are few types of errors I'm handling and if there's no error I run additional regressions.
      I thought that providing the whole code will be distracting and unnecessary, I might be wrong about it.

      Comment


      • #4
        The code must be of the form

        Code:
        if ....
        else ...
        with nothing else in between. The else code must follow the if code (understanding that braces { } may delimit such code) with no other code in between.

        That is not true of your code in #1.

        Otherwise, did you try my code? If not, what code did you try and what happened?

        Your impulse to simplify the problem presented is good if and only if you isolate the real problem. "didn't solve my problem" and "the problem remains" aren't, unfortunately, error reports I can react to. .

        Comment


        • #5
          Thanks for the patience.

          The error that stops the code is always the same: _b not allowed when e(b) is not present.
          I've tried:
          1. removing di command inside the error handle part
          2. replacing else command with a 2nd if command for when _rc==0 (as shown)
          3. adding the cap reg command again before the 2nd if command (as shown)
          4. skipping this whole part for the year 2000 specifically. The code gives the same error for the next problematic year (2006).
          5. adding a display command right after the 2nd if command (as shown) - it never displays it which is very weird to me.



          Code:
          forvalues year = 1993/2009 {
                      di "Subset of year `year'"
          
                      
                      *** Controlled Regression 
                      cap reg `q' treat `controls' if survey_year==`year', robust
                      
                      
                      ** Error Handler 
                      if _rc!=0 {    
                          // year not surveyed marked by "-"
                          if inlist(`year', 2006, 2008) {    
                              post event_study_reg (`group') ("${treat_title}") ("${control_title}") ("`q'") ("${`q'_label}") (`year') ///
                                  ("-") (.) (.) (.) (.) (.) (.) (.) (.) (.) (.) (.) (.)
                          }
                          
                          // survey cant be coded marked by "0"
                          else if inlist(`year', 2000) {  
                              post event_study_reg (`group') ("${treat_title}") ("${control_title}") ("`q'") ("${`q'_label}") (`year') ///
                                  ("0") (.) (.) (.) (.) (.) (.) (.) (.) (.) (.) (.) (.)
                          }
                          
                          // else: question isnt in this survey marked by "."
                          else {
                              post event_study_reg (`group') ("${treat_title}") ("${control_title}") ("`q'") ("${`q'_label}") (`year') ///
                                  (".") (.) (.) (.) (.) (.) (.) (.) (.) (.) (.) (.) (.)
                          }
                      }
          
                      cap reg `q' treat `controls' if survey_year==`year', robust   // added this to make sure the captured error is relevant
                      
                      ** No Error            
                      if _rc==0 {    // alternative to else command
          
                          di "check 1" // this isn't displayed for the bad year (2000)
          
                          * Post Controlled Regression Results
                          local beta = _b[treat]
                          local t = _b[treat]/_se[treat]
                          local upper = _b[treat] + invttail(e(df_r),0.05)*_se[treat]
                          local lower = _b[treat] - invttail(e(df_r),0.05)*_se[treat]
                              // NOTE - the upper and lower CI bounds are for 10% sig. lvl
                          
                      } 
          }

          Comment


          • #6
            Thanks for your fuller code. I can't check against data and I can't see what is wrong either.

            Is treat the full name of the variable concerned?

            EDIT

            What does this show?

            Code:
            egen y = group(survey_year), label
            
            su y, meanonly
            
            forvalues y = `r(min)'/`r(max)' {
                su year if y == `y', meanonly
                local year = r(min)
                cap reg `q' treat `controls' if survey_year==`year', robust  
                di `year' " " _rc " " _b[treat]            
            }
            Last edited by Nick Cox; 27 May 2020, 01:50.

            Comment


            • #7
              The output is:
              Code:
              Question: q1
              1993 0 -.91449972
              1994 0 -.66929491
              1995 0 -.73160581
              1996 0 -.65497505
              1997 0 -.79092984
              1998 0 -.73974728
              1999 0 -.19787961
              2000 2000 _b not allowed when e(b) is not present
              r(111);
              I know the regression cant run for survey_year 2000 and the error is 2000 - I cant figure why it keeps stepping into the 2nd if command (originally the else command).




              Note that I needed to change the line shown:

              Code:
               * Nick's code (var year doesnt exist)
              su year if y == `y', meanonly
              
               * What I used
              su survey_year if y == `y', meanonly

              Comment


              • #8
                Sorry about my typo. I can't add more ideas. Somebody else may be able to help.

                Comment


                • #9
                  For future readers :
                  I had a problem in the "else" section which is unrelated.

                  For those who tried to help - Thanks again and sorry.

                  Comment

                  Working...
                  X