Announcement

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

  • program and loop

    Dear All,

    I am trying to run the following code:

    Code:
    cap program drop myboot
    cap drop fitted imr
    
    program define myboot, eclass
        preserve
        syntax [if] [in]    
        probit credits_dummy $instruments log_isee1 if female == `i'
        predict double fitted`i', xb    
        gen double imr`i' = normalden(fitted`i') / normal(fitted`i')    
        ivreg2 std_gpa (autonuni=$instruments) imr`i' if female == `i', cluster(cds) endog(autonuni)
        matrix b`i'=e(b)  
        ereturn post b`i'  
        ereturn local cmd="bootstrap"
    end
    
    forvalues i=0/1{
    bootstrap _b`i', seed(12345) reps(500): myboot
    est store heck`i'
    }
    However, Stata replies:

    Code:
    invalid syntax
    an error occurred when bootstrap executed myboot
    I cannot figure out where the mistake is. Any hint?

    Thanks in advanced for your kind help.

    Dario
    Last edited by Dario Maimone Ansaldo Patti; 16 Dec 2024, 10:08.

  • #2
    Local macros are exactly as the name implies: local to the code that uses them. More at

    Code:
    SJ-20-2 dm0102  . . . . . . . . . Stata tip 138: Local macros have local scope
            . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .  N. J. Cox
            Q2/20   SJ 20(2):499--503                                (no commands)
            focuses on a common misunderstanding of how local macros work
    So your program can't see or otherwise sense the loop number in which it is called. You need to pass that number directly to the program.

    One way that might work -- I've not looked carefully at the rest of your code, let alone tested anything -- is

    Code:
     
     syntax [if] [in] , i(real)
    Code:
      
     bootstrap _b`i', seed(12345) reps(500): myboot, i(`i')
    On "thanks in advance" see (e.g.) https://languagetool.org/insights/po...ou-in-advance/

    Comment


    • #3
      Nick gives excellent advice, as always.

      Here's another way to accomplish the results. You never actually use the [if] and [in] capabilities in program myboot. So a simplification would be to remove the -syntax- command altogether and replace it with an appropriate -args- command that will establish local macro i within program myboot:
      Code:
      program define myboot, eclass
          preserve
          args i    
          probit credits_dummy $instruments log_isee1 if female == `i'
          predict double fitted`i', xb    
          gen double imr`i' = normalden(fitted`i') / normal(fitted`i')    
          ivreg2 std_gpa (autonuni=$instruments) imr`i' if female == `i', cluster(cds) endog(autonuni)
          matrix b`i'=e(b)  
          ereturn post b`i'  
          ereturn local cmd="bootstrap"
      end
      
      forvalues i=0/1{
          bootstrap _b`i', seed(12345) reps(500): myboot `i'
          est store heck`i'
      }
      This might be a little simpler. (It also presupposes that what you have shown of program myboot is really the whole thing, and that you don't actually use [if] and [in] there.

      Comment


      • #4
        Nick Cox thanks for pointing this out. Regarding "thanks in advance" I was not meant to be pretentious. I read careful the link you sent me and in the future I will change that sentence, using one of those suggested in the link.

        Clyde Schechter. Yes that is the whole story. I am not going to use [if] or [in] in myboot. Thanks for your suggestion.

        Comment


        • #5
          Clyde Schechter Dear Clyde, when I try to run the code above, I get the following error message:

          Code:
          (running myboot on estimation sample)
          _b0 not found
          error in expression: _b0
          Do you have any idea why this happens? Thanks for any help you may provide.

          Dario

          Comment


          • #6
            Apparently it works if I do the following:

            Code:
            program define myboot, eclass
            preserve
            args i
            probit credits_dummy $instruments log_isee1 if female == `i'
            predict double fitted`i', xb
            gen double imr`i' = normalden(fitted`i') / normal(fitted`i')
            ivreg2 std_gpa (autonuni=$instruments) imr`i' if female == `i', cluster(cds) endog(autonuni)
            matrix b`i'=e(b)
            ereturn post b`i'
            ereturn local cmd="bootstrap"
            restore
            end
            
            forvalues i=0/1{
            bootstrap `b`i'', seed(12345) reps(500): myboot `i'
            est store heck`i'
            }
            I am not sure it is correct
            Last edited by Dario Maimone Ansaldo Patti; 17 Dec 2024, 03:58.

            Comment


            • #7
              Well, it produces the correct result , but not for the reason you think! And I don't recommend coding it this way. The problem is that there is no local macro b`i' defined. So your -bootstrap- command expands to -bootstrap, seed(12345) reps(500): myboot #- (where # is replaced by either 0 or 1 depending on which iteration of the loop is running. Notice that there is nothing between the -bootstrap- and the comma, because local macro b`i' does not exist. Now, by default, when -bootstrap- calls a program that modifies -ereturn-, as your myboot program does, if no expressions are specified in the -bootstrap- command, as is inadvertently the case here, -bootstrap- returns the _b matrix. Well, if you look at program myboot, the thing it does return, matrix b0 or b1, depending on which iteration of the loop is running, is created as a copy of e(b), which contains the same thing as _b. So you are getting what you wanted, but in a rather roundabout way.

              Comment


              • #8
                Clyde Schechter thank you! Very clear and useful as usual.

                Comment

                Working...
                X