Announcement

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

  • Median Split Loop

    Hi there...

    ...and a heads-up - I'm not an expert on writing loops. So, not really a surprise why my code isn't working but I can't figure out why. I have 12 variables and want to perform a median split on each. My code stops running after the first median split, saying that needs_1_median already exists.

    Here is my code:

    local vars "needs_1 needs_2 needs_3 needs_4 needs_5 needs_6 needs_7 needs_8 needs_9 needs_10 needs_11 needs_12"
    foreach var in `vars' {
    sum `var',d
    local p50_`var' = r(p50)
    gen `var'_median = 0
    replace `var'_median = 1 if `var'>= `p50_var' & missing!(`var')
    tab `var'_median
    }

    Can anyone help?

  • #2
    Welcome to the Statalist. A couple of minor syntax errors make this fail, but the loop itself is ok, and the use of code delimiters make it easier to read. I've highlighted the changes in red.

    Code:
    * no quotes are needed around the variable list, but they don't make a difference in this code example, though they can bite elsewhere.
    local vars needs_1 needs_2 needs_3 needs_4 needs_5 needs_6 needs_7 needs_8 needs_9 needs_10 needs_11 needs_12
    foreach var in `vars' {
    sum `var',d
    local p50_`var' = r(p50)
    * you will need to specify that the original variable is not missing, or else missing values will be recorded as 0.
    gen `var'_median = 0  if !missing(`var')
    * some quotes were missing here, as macro expansion will first replace the name of the variable and then the stored macro will be substituted.
    * the logical negation (!) must come before the function missing()
    replace `var'_median = 1 if `var'>= `p50_`var'' & !missing(`var')
    tab `var'_median
    }
    Some simplification can be made, according to taste. Here I modified the variable list and used the auto dataset to demonstrate.

    Code:
    sysuse auto, clear
    
    local vars mpg price rep78
    foreach var in `vars' {
      qui sum `var', d
      * here I make the logical condition evaluate in one line, and don't need to the intermediate step of storing the median to a local macro
      gen byte `var'_median = inrange(`var', `r(p50)', .) if !mi(`var')
      tab `var'_median
    }
    Last edited by Leonardo Guizzetti; 30 Sep 2021, 08:53.

    Comment


    • #3
      Given the question did not post any sample data, I am not able to figure out why it didn't work. From the codes, I don't see any overwrite problem, my guess is that you might have tried to re-run this chunk again, and that "gen `var'_median = 0" caused an overwrite warning. One thing you can try is to add another line above it: "capture drop `var'_median", then generate it. This should solve the warning.

      And, I think the code can be simplified (And I'm not sure if ! can be placed after missing. I always put that before.)
      Code:
      forvalues x = 1/12{
          quietly sum needs_`x', detail
          capture drop needs_`x'_median
          gen needs_`x'_median = (needs_`x' >= r(p50)) if !missing(needs_`x')
          tab needs_`x'_median
      }
      Last edited by Ken Chui; 30 Sep 2021, 09:15.

      Comment


      • #4
        Ken Chui and Leonardo Guizzetti make a good point I would have made, which is just to use r(p50) directly. Let me bang the table (rationally) on this.

        Putting it into a local and then taking it out again is quite unneeded (and as seen here, a source of bugs if you get it wrong).

        Indeed Leonardo Guizzetti could have cut out another local with
        Code:
         
         foreach var in mpg price rep78
        We are touching on matters of taste here, and indeed if you don't prefer simpler and concise code to complicated and longer code, then you will choose differently.

        Ken meant to type forvalues -- I hope that's evident.

        Comment


        • #5
          Originally posted by Nick Cox View Post

          Ken meant to type forvalues -- I hope that's evident.
          Thanks Nick! I've edited that typo.

          Comment

          Working...
          X