Announcement

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

  • Options not allowed

    Hi all.

    Here is an excerpt of a program that I am constructing for university


    simulate beta_1=r(mean) ,rep(500) seed(300344572) :sim 10, 10

    clear // clearing past iterations of the program

    . capture program drop sim // allows program reuse

    .
    . /** Start of Program */
    .
    . program sim,rclass // defining program
    1. set trace on
    2. args p t // p = number of individuals, t = number of periods
    3.
    . /** Initialise Level 2 program structure*/
    . set obs `p' // set the number of people to the input argument
    4. generate person = _n // creates an indexed list of people
    5. end

    At line 4, it crashes, displaying the message "options not allowed" and an error code of r(101).

    I am hoping that you can help me to find this error. I am sure it is something super simple.

    Kind Regards
    Christopher Keegan

  • #2
    To start with, remove the comma between the two 10s.

    After you fix that, be sure to have the program return something in a return scalar called "mean".

    Comment


    • #3
      As Joseph Coveney implies, Stata is parsing arguments by spaces. So the first argument is taken to be

      Code:
      10,
      and Stata thinks that you're trying to specify options which aren't allowed with


      Code:
      set obs 10,

      Comment


      • #4
        Great. Thanks, guys. The bug is now fixed.

        I have another question for you though;

        In the next part of my code :

        forvalues i = 1(1)(`obs'){ // Steps through each observation of lambda_t
        if period[`i'] != `x'{
        replace `x' = `x' + 1
        replace `c' = rnormal(0,1)
        }
        replace lambda_t(i) = `c'
        }

        All variables are defined properly. The bold line is the line that Stata has a problem with. I am not sure whether it has something to do with how I am using the if statement.

        Any help is appreciated

        Kind Regards
        Christopher Keegan

        Comment


        • #5
          So, what is the error message? All I can see in what you show us is that local macro x has not been defined. Neither has local macro c.

          From the fact that the previous command evidently worked, we can guess that local macro obs has been defined.

          You need to show us a complete self-contained example. In fact, http://xyproblem.info/ may apply.

          Looking ahead

          Code:
          replace lambda_t(i) = `c'
          looks quite wrong. You may want instead

          Code:
          replace lambda_t = `c' in `i'

          Comment


          • #6
            You are right.

            Here is the full code with the line in question in bold:

            program sim,rclass // defining program
            clear
            set trace on
            args p t // p = number of individuals, t = number of periods

            /** Initialise Level 2 program structure*/
            set obs `p' // set the number of people to the input argument
            generate person = _n // creates an indexed list of people
            generate gamma_i = rnormal(0,1) // create an individual fixed effect for
            // each person

            /** Initialise Level 1 program structure*/
            expand `t' // expands each individual entry by number of periods
            bysort person: generate period = _n // For each individual, create a
            // indexed list from 0 to t for time
            bysort period person: generate lambda_t = 0 // create a fixed effect for each time
            // period and set to 0
            local x = 1
            local c = rnormal(0,1) // initialise parameters for loop
            local obs = `p'*`t'
            forvalues i = 1(1)(`obs'){
            if period(`i') != `x' { //
            replace `x' = `x' + 1
            replace `c' = rnormal(0,1)
            }
            replace lambda_t = `c' in `i'
            }
            bysort person period: generate X_it = 0
            local per = 1, local treat = 0
            forvalues i = 1(1)(`p'){
            replace treat = runiform(2, `t' - 1)
            while `per' == `i'{
            forvalues j = 1(1)(`t'){
            if(period((`t'*`i')-(1-`j')) >= `treat'){
            replace X_it = 1 in (`t'*`i')-(1-`j')
            }
            }
            }
            replace `per' = `per' + 1
            }
            generate u_it = rnormal(0,1)
            generate y = person*gamma_i + period*lambda_t + 3.6*X_it + 3*X_it*period + u_it
            end

            simulate beta_1=r(mean) ,rep(500) seed(300344572) :sim 50 20

            The error message is incorrect syntax r(198)

            Kind regards
            Christopher Keegan

            Comment


            • #7
              This is what you posted. Just by using CODE delimiters (FAQ Advice #12), it's made more readable.

              Code:
               
              program sim,rclass // defining program
              clear
              set trace on
              args p t // p = number of individuals, t = number of periods
              
              /** Initialise Level 2 program structure*/
              set obs `p' // set the number of people to the input argument
              generate person = _n // creates an indexed list of people
              generate gamma_i = rnormal(0,1) // create an individual fixed effect for 
              // each person
              
              /** Initialise Level 1 program structure*/
              expand `t' // expands each individual entry by number of periods
              bysort person: generate period = _n // For each individual, create a 
              // indexed list from 0 to t for time
              bysort period person: generate lambda_t = 0 // create a fixed effect for each time 
              // period and set to 0
              local x = 1
              local c = rnormal(0,1) // initialise parameters for loop
              local obs = `p'*`t'
              forvalues i = 1(1)(`obs'){
              if period(`i') != `x' { // 
              replace `x' = `x' + 1
              replace `c' = rnormal(0,1)
              }
              replace lambda_t = `c' in `i'
              }
              bysort person period: generate X_it = 0
              local per = 1, local treat = 0
              forvalues i = 1(1)(`p'){
              replace treat = runiform(2, `t' - 1)
              while `per' == `i'{
              forvalues j = 1(1)(`t'){
              if(period((`t'*`i')-(1-`j')) >= `treat'){
              replace X_it = 1 in (`t'*`i')-(1-`j')
              }
              }
              }
              replace `per' = `per' + 1
              }
              generate u_it = rnormal(0,1)
              generate y = person*gamma_i + period*lambda_t + 3.6*X_it + 3*X_it*period + u_it 
              end
              
              simulate beta_1=r(mean) ,rep(500) seed(300344572) :sim 50 20
              Now I am going to make some cosmetic changes, including

              * indents within loops, which are really vital for readability
              * more blank lines here and there
              * less crowded comments

              and some code changes that are just simplifications:

              * if a by: prefix makes no difference to what is calculated, omit it
              * Stata knows _N as the number of observations
              * your forval calls can all be simplified

              Code:
               
              // defining program
              program sim, rclass 
              
              clear
              set trace on
              // p = number of individuals, t = number of periods
              args p t 
              
              // initialise Level 2 program structure 
              // set the number of people to the input argument
              set obs `p' 
              // creates an indexed list of people
              generate person = _n 
              // create an individual fixed effect for each person
              generate gamma_i = rnormal(0,1) 
              
              // initialise Level 1 program structure
              // expands each individual entry by number of periods
              expand `t' 
              // for each individual, create a indexed list from 0 to t for time
              // !!! NJC the comment is wrong, as the values run 1 to t 
              bysort person: generate period = _n 
              
              // create a fixed effect for each time period and set to 0
              generate lambda_t = 0 
              
              // initialise parameters for loop
              local x = 1
              local c = rnormal(0,1) 
              
              // !!! NJC explain loop  
              forvalues i = 1/`=_N'{
                  if period(`i') != `x' { // 
                      replace `x' = `x' + 1
                      replace `c' = rnormal(0,1)
                  }
                  replace lambda_t = `c' in `i'
              }
              
              // !!! NJC explain this too 
              // !!! you stopped commenting... 
              generate X_it = 0
              local per = 1, local treat = 0
              
              forvalues i = 1/`p' {
                  replace treat = runiform(2, `t' - 1)
              
                  while `per' == `i'{
                      forvalues j = 1/`t' {
                          if (period((`t'*`i')-(1-`j')) >= `treat') {
                              replace X_it = 1 in (`t'*`i')-(1-`j')
                          }
                      }
                  }
                  replace `per' = `per' + 1
              }
              
              generate u_it = rnormal(0,1)
              generate y = person*gamma_i + period*lambda_t + 3.6*X_it + 3*X_it*period + u_it 
              end
              
              simulate beta_1=r(mean) ,rep(500) seed(300344572) :sim 50 20
              Now I am going to comment on what look like bugs or at least problems to me. To shorten what anyone has to read, I am going to omit comments.

              Commenting is sometimes under instruction: some people grading code expect a certain density and style.

              I don't often comment in my code, and people are free to disapprove of that. StataCorp don't comment much either, and I think some of the reasons are the same.

              Code:
               
              program sim, rclass 
              * PROBLEM 1 this program is r-class but returns no such results 
              
              clear
              set trace on
              args p t 
              
              set obs `p' 
              generate person = _n 
              generate gamma_i = rnormal(0,1) 
              
              expand `t' 
              bysort person: generate period = _n 
              
              generate lambda_t = 0 
              
              local x = 1
              local c = rnormal(0,1) 
              
              forvalues i = 1/`=_N' {
                  if period(`i') != `x' { 
              * PROBLEM 2 you need [ ] not () 
                      replace `x' = `x' + 1
              * PROBLEM 3 you can't use -replace- on a local macro 
                      replace `c' = rnormal(0,1)
              * PROBLEM 4 = PROBLEM 3 
                  }
                  replace lambda_t = `c' in `i'
              }
              
              * PROBLEM 5 I don't know what this loop is designed to do. 
              * What do you want to go in lambda_t? If it is a different 
              * random normal deviate in each observation, then you can do 
              * that without a loop. If it's a distinct random normal 
              * deviate for each panel (or each time), you need different code. 
              
              generate X_it = 0
              local per = 1, local treat = 0
              * PROBLEM 6 Quite illegal. You need two lines 
              * local per = 1 
              * local treat = 0 
              
              forvalues i = 1/`p' {
                  replace treat = runiform(2, `t' - 1)
              * PROBLEM 7 = PROBLEM 3 
              
                  while `per' == `i'{
                      forvalues j = 1/`t' {
                          if (period((`t'*`i')-(1-`j')) >= `treat') {
                              replace X_it = 1 in (`t'*`i')-(1-`j')
                          }
                      }
                  }
              
              * PROBLEM 8 you are never going to exit this -while- loop 
              * PROBLEM 9 you need period[] not period() 
              * PROBLEM 10 I doubt the -in- will work without calculating 
              * local where = (`t' * `i') - (1 - `j') 
              * before 
              * ... in `where' 
              
                  replace `per' = `per' + 1
              * PROBLEM 11 = PROBLEM 3 per is a local macro 
              * PROBLEM 12 = PROBLEM 8 this is outside your -while- loop and should be
              * inside 
              }
              
              generate u_it = rnormal(0,1)
              generate y = person*gamma_i + period*lambda_t + 3.6*X_it + 3*X_it*period + u_it 
              * PROBLEM 13 no need for u_it; just add rnormal(0, 1) directly 
              * PROBLEM 14 = PROBLEM 1 what are returning as r class results?  
              end
              
              simulate beta_1=r(mean) ,rep(500) seed(300344572) :sim 50 20
              * PROBLEM 15 = PROBLEM 1 where is -simulate- going to find r(mean)
              Now some over-arching comments. I don't claim to understand all of what you are trying to do, and I've not tried testing it. I do note that the line you flagged as problematic in #4 was not actually the line in your code, because #4 uses square brackets and your program uses parentheses. So, there lies a simple moral: always copy and paste what doesn't work. Don't ever rewrite code; you might by accident fix the code, or (more likely) reintroduce other errors.

              Comment


              • #8
                The following example demonstrates two things.
                Code:
                . local obs 3
                
                . forvalues i = 1(1)(`obs'){
                  2. display "loop"
                  3. }
                invalid syntax
                r(198);
                
                . forvalues i = 1(1)`obs'{
                  2. display "loop"
                  3. }
                loop
                loop
                loop
                
                .
                First, errors occurring as part of a block of code - including any command that appears on the line opening the block - are reported at the end of the block. So while you didn't assume the syntax error was on the
                Code:
                }
                immediately preceding, it wasn't necessarily on the line before that, either.

                Second, it pays attention to read carefully the documentation for commands you are using. The output of help forvalues tells us
                Code:
                Syntax
                
                        forvalues lname = range {
                                Stata commands referring to `lname'
                        }
                
                    where range is
                
                                            #1(#d)#2      meaning #1 to #2 in steps of #d    
                                            #1/#2         meaning #1 to #2 in steps of 1      
                                            #1 #t to #2   meaning #1 to #2 in steps of #t - #1
                                            #1 #t :  #2   meaning #1 to #2 in steps of #t - #1
                which offers no support for the second set of parentheses in your forvalues command.

                Added in edit: this crossed with Nick's much more complete analysis, although it dealt only implicitly with the error in your forvalues syntax.
                Last edited by William Lisowski; 28 Jun 2019, 05:13.

                Comment


                • #9
                  William Lisowski spotted something I only fixed by accident. I am entirely happy about that.

                  The key point is that as parentheses have specific meaning for forvalues, you can't expect forvalues to ignore parentheses that are merely cosmetic.
                  Last edited by Nick Cox; 28 Jun 2019, 05:19.

                  Comment


                  • #10
                    Thank you, Nick and William, for the analysis.

                    I have looked everywhere over the net but I can not find how to change local variables. If it is not replace (local var) then what do you do when you want to change the value of a local variable???

                    Kind Regards
                    Christopher Keegan

                    Comment


                    • #11
                      Looking everywhere sounds too time-consuming to me. It's hard for me to remember how I learned this -- I think most of what I learned first about Stata programming was based on looking at Stata programs -- but the underlying question of where this is explained is naturally fair.

                      For a Stata learner-programmer my standard recommendation would be to try

                      Code:
                      help local
                      which brings up

                      Code:
                      help macro
                      which in turn is fairly terse, but a link there to the pdf documentation brings up examples like

                      Code:
                      local x = `x' + 1 
                      which I guess is what you seek.

                      A local macro is defined (which includes being re-defined) by giving an expression which is either copied or evaluated. The expression can (and often does) include a reference to the same macro, and thus use of its current contents.

                      Many programming languages allow statements like

                      Code:
                      x = 42
                      x = x + 1
                      and that is fine in Mata, but Stata always wants a command first, as in

                      Code:
                      generate x = 42
                      replace x = x + 1
                      and as in the first statement in this post for local macros.


                      A serious (not pedantic) detail is that Stata documentation never talks about local variables. They are local macros and in most ways not only are not variables in Stata's sense, but also are not even like variables in Stata's sense. More in the same annoying style can be found at at https://www.stata.com/statalist/arch.../msg01258.html

                      I wouldn't start by Googling. I would always start with Stata's own help and then the manuals.

                      Comment

                      Working...
                      X