Announcement

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

  • Masterthesis - foreach loop

    Hey!
    I seek to evaluate whether participants in an experiment (n=700) who had a BMI above 30 and were randomly assigned to 3 groups with incentives (control group 0€, group1: 150€ and group2: 300€) to lose 6-8% of their body weight had persistent labor market effects over 22 months after the start of the experiment. I have a data set available for this. Using the foreach loop, I would like to find out whether significant differences between the control group and the treatment groups occurred over the three phases of the experiment. For this purpose, I look at the employment status in each phase and subdivide between employed and unemployed. The following code is intended to investigate this. However, I keep getting the error message: "too few ')' or ']' r(132);", even though the number of brackets is clearly sufficient. For the first phase I have the variables treat1_or for group1 and treat2_or for group2.
    What am I doing wrong that no data is saved in the desired file folders?

    local path "C:\Users\Florian Frankl\Desktop\MA"

    global employed_phasen "employment_Abnehmphase employment_Followup employment_Haltephase"
    global unemployment_phasen "unemployment_Abnehmphase unemployment_Followup unemployment_Haltephase"


    foreach var of varlist $employed_phasen $unemployment_phasen {
    local l`var' : variable label `var'
    matrix drop _all
    reg `var' treat1_or treat2_or if adm_v2==2&drop==0

    local pvalue_3x4 = (2 * ttail(e(df_r), abs(_b[treat1_or]/_se[treat1_or])))
    local pvalue_3x4 = round(`pvalue_3x4', 0.001)
    local pvalue_3x5 = (2 * ttail(e(df_r), abs(_b[treat2_or]/_se[treat2_or])))
    local pvalue_3x5 = round(`pvalue_3x5', 0.001)


    test treat1_or=treat2_or
    local pvalue_diff_3x6=r(p)
    local pvalue_diff_3x6=round(`pvalue_diff_3x6',0.001)
    local n_a=e(N)
    matrix b_a=e(b)
    local btreat1_or=round(b_a[1,1],0.001)
    matrix se_a=e(V)
    local setreat1_or=se_a[1,1]
    local setreat1_or=round(sqrt(`setreat1_or'),0.001)
    local btreat2_or=round(b_a[1,2],0.001)
    local setreat2_or=se_a[2,2]
    local setreat2_or=round(sqrt(`setreat2_or'),0.001)
    cap drop esam1
    cap gen esam1=e(sample)==1
    matrix drop _all
    mean `var' if control_or==1&esam1==1&drop==0

    test `var'
    local pvalue_3x2=r(p)
    local pvalue_3x2=round(sqrt(`pvalue_3x2'),0.001)
    *
    local ntreat1_or=e(N)
    matrix mtreat1_or=e(b)
    local mtreat1_or= mtreat1_or[1,1]
    local mtreat1_or=round(`mtreat1_or',0.001)
    matrix msetreat1_or=e(V)
    local msetreat1_or= msetreat1_or[1,1]
    local msetreat1_or=round(sqrt(`msetreat1_or'),0.001)
    matrix drop _all
    mean `var' if treat2_or==1&esam1==1&drop==0
    *
    test `var'
    local pvalue_3x3=r(p)
    local pvalue_3x3=round(sqrt(`pvalue_3x3'),0.001)
    *
    local ntreat2_or=e(N)
    matrix mtreat2_or=e(b)
    local mtreat2_or=mtreat2_or[1,1]
    local mtreat2_or=round(`mtreat2_or',0.001)
    matrix msetreat2_or=e(V)
    local msetreat2_or=msetreat2_or[1,1]
    local msetreat2_or=round(sqrt(`msetreat2_or'),0.001)

    matrix a0`var'=(`mcontrol_or',`mtreat1_or',`mtreat2_or',` btreat1_or',`btreat2_or',. \ `msecontrol_or',`msetreat1_or',`msetreat2_or',`set reat1_or',`setreat2_or',. \ `pvalue_3x1',`pvalue_3x2',`pvalue_3x3',`pvalue_3x4 ',`pvalue_3x5', `pvalue_diff_3x6' \ ///
    `ncontrol_or',`ntreat1_or',`ntreat2_or', `n_a',.,. )


    matsave a0`var', path("$path\Log-Files\Sub") saving replace
    preserve
    use "$path\Log-Files\Sub\a0`var'.dta", clear

    replace _rowname="a0b_`l`var''" if _rowname=="r1"
    replace _rowname="a0se_`l`var''" if _rowname=="r2"
    replace _rowname="a0p_`l`var''" if _rowname=="r3"
    replace _rowname="a0n_`l`var''" if _rowname=="r4"
    save "$path\Log-Files\Sub\a0`var'.dta", replace

    use "$path\Tabellen\table_abnehm.dta", clear
    append using "$path\Log-Files\Sub\a0`var'.dta"
    save "$path\Tabellen\table_abnehm.dta", replace
    restore
    }

    I would be more than thankful to receive any kind of help. Thank you for reading.

    Best regards from Germany

  • #2
    You can try using:

    Code:
    set trace on
    before rerunning your code to see which line is giving you trouble. Additionally, it is helpful to wrap your code in the CODE tags when posting on the forum.

    Comment


    • #3
      It is very difficult to troubleshoot a long block of code, especially for issues like parenthesis balance which can be visually elusive, with nothing more to go on. I would advise you to at least zoom in on the particular line that is producing the problem. Before the -foreach- loop put in the following commands:
      Code:
      set tracedepth 1
      set trace on
      and rerun the code.

      You will get a lot of additional output beyond the usual. And, in particular, you will be able to see which command inside the -foreach- loop is throwing the error. Then you can focus your efforts on fixing that.

      If I had to make a guess with a gun held to my head, I would bet on
      Code:
      matrix a0`var'=(`mcontrol_or',`mtreat1_or',`mtreat2_or',` btreat1_or',`btreat2_or',. \ `msecontrol_or',`msetreat1_or',`msetreat2_or',`set reat1_or',`setreat2_or',. \ `pvalue_3x1',`pvalue_3x2',`pvalue_3x3',`pvalue_3x4 ',`pvalue_3x5', `pvalue_diff_3x6' \ ///
      `ncontrol_or',`ntreat1_or',`ntreat2_or', `n_a',.,. )
      as the source of the error. I say this because it is a very long command. You have put in a \\\ line break in a very unusual place, a place where the line has extended far, far beyond the length that most people wish to restrict to. Also, as displayed here in the Forum, the line breaks at `set reat1_or',`setreat2_or',. \ with no \\\ informing Stata that the next line is a continuation of the same command. Of course, I cannot know if that is how the code actually looks in the do-editor. But if it does, then the part from the beginning of the first line through `set reat1_or',`setreat2_or',. \ is a separate line which contains an opening parenthesis after the = sign, but no matching closing parenthesis. The solution would be to add a \\\ to allow Stata to connect this line to the rest of the command. Again, though, what I'm seeing may be an artifact of how your code is being displayed in the Forum editor, not how it is in your do-file editor.

      Anyway, the -trace- output suggested above will show you where it is. Then you can focus your efforts on that one command.

      As an aside, I see you are going through considerable effort to calculate standard errors from e(V) and p-values from e(b) and those standard errors following a regression at the top of the loop. This is not necessary unless you are using some ancient version of Stata. All Stata estimation commands leave behind a matrix, r(table), which you can pick up and store as a real matrix. It contains all of these things neatly laid out. This will greatly simplify your efforts and shorten your loop considerably. It will make the code much more transparent, and easier to debug, explain, and maintain.

      Added: Crossed with #2.
      Last edited by Clyde Schechter; 11 Aug 2023, 09:00.

      Comment


      • #4
        Thank you very much for answering so fast. I will try that and report if it is working.

        Comment


        • #5
          @Clyde Schlechter:
          Thanks again for your detailed answer. However, I couldn't manage to find the mistake. The code is mainly based on a code I received from my supervisor of the master thesis and now I have to apply it to my concrete task. Therefore, it may well be that this code is based on an old version of Stata. However, now I would like to test your approach and write the code again myself without concentrating so much on calculating standard errors and p-values. Since I am an absolute newbie in the field of coding, I wanted to ask you to explain me how I generate the real matrix, provided as you said that this is stored anyway? Where can I access it after writing the code myself?

          Comment


          • #6
            So, for example, to create the local macros containing the coefficients, standard errors, and p-values associated with variables treat1_or and treat2_or:
            Code:
            reg `var' treat1_or treat2_or if adm_v2==2&drop==0
            matrix M = r(table)
            
            local pvalue_3x4 = M["pvalue", "treat1_or"]
            local pvalue_3x5 = M["pvalue", "treat2_or"]
            
            test treat1_or=treat2_or
            
            local pvalue_diff_3x6=r(p)
            
            local btreat_1or = M["b", "treat1_or"]
            local setreat_1or = M["se", "treat1_or"]
            local btreat_2or = M["b", "treat2_or"]
            local setreat_2or = M["se", "treat2_or"]
            Note, by the way, that I do not do any of the rounding that was used in your code. It is a bad idea to round numbers before using them in calculations. This leads to rounding errors that, while they may ultimately cancel out, sometimes accumulate to substantial errors. If you round at all, you should do so only with final results. Moreover, bear in mind that because the computer works in binary, rounding to .001 (or anything other than a negative power of 2) will not be exact and actually increases the error in your results. In my own work, I never round, except to the nearest integer (and that only rarely). To produce a less ragged display than the raw numbers, I apply display formats to them instead, and leave the actual numbers themselves as they are. In other words, instead of -replace x = round(x, 0.001)- I would not change x. But I would -format x %04.3f-. That way whenever you look at x in an output listing or in the data browser it will be displayed rounded to 3 decimal places. But internally, x remains unchanged, and if you ultimately perform further calculations with it, your calculations will be based on the real thing, rather than on an erroneous 3-decimal place proxy.

            I also notice that your original code creates matrices out of all those b's and se's and pvalues that you first calculate as local macros. But actually, since all of that is already in r(table) there may be no reason to do all of that, as I don't see you using these local macros for any other purpose. The matrix M created in the code shown in this post contains all of that information (and more). You might want to just remove from M the rows and columns that you are not interested in. (Read -help matrix extraction- if you are not sure how that is done.)

            So, what I have shown you is just an example of how you can simplify your code. Nearly everything in your code can be done with some simple commands involving that matrix M. It probably all reduces to a handful of lines. And most likely if you go through it and change everything to this approach you will have removed the line that was causing that error message about unbalanced parentheses.

            Comment

            Working...
            X