Announcement

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

  • Loop with condition on (n-1) previous variables

    Dear Stata users,

    I have poor programming skills and I have benefited from the Statalist treasures for many years. The time has come for me to post since I could not find any answer, even after spending a rather shocking amount of time on what is probably a simple question for many of you.

    I have a dataset with 12 variables (month1-12). They take the value 0 (no activity) to 3 (high activity) for small businesses.
    I want to put a condition inside a loop that could be written literally: "all the previous month variables are equal to 0"

    For now the code looks like this:

    forvalues i=1/12{
    replace outcome_max=$outcome if month`i'=1 & month1-month`=`i' - 1'==0
    replace oucome_min=outcome_max/ratio if month`i'=1 & month1-month`=`i' - 1'==0
    replace outcome_avg=(outcome_max+oucome_min)/2 if month`i'=1 & month1-month`=`i' - 1'==0
    }

    Of course, the condition "month1-month`=`i' - 1'==0 " does not work (invalid syntax), since it is but a naive translation of the sentence "all previous month =0"

    How can I make a flexible reference to all previous month ?
    In other words, for month 3 the condition would be month1==0 & month2==0, and so on.
    It is probably some simple local macro that I cannot think of for the moment, which would allow nesting all the "==0".

    Many thanks in advance for your time & undoubtedly powerful skills
    Axel

  • #2
    The biggest complication is getting your data layout (do you also have 12 outcome vars for each company, or just one?) and understanding what needs to be done. The rest is trivial in Stata. Here is a rough cut that counts companies active in any of the previous months for each month from 2 onwards:

    Code:
    clear
    
    input m1 m2 m3 m4 m5 m6 m7 m8 m9 m10 m11 m12
    0 0 0 0 1 1 0 0 1 1 1 0
    0 0 1 0 1 1 1 1 1 1 1 1
    1 0 0 1 0 0 0 0 0 0 0 0
    0 1 1 1 1 1 1 1 1 1 0 0
    0 0 0 0 0 0 0 0 0 0 0 0
    end
    
    list
    
    tempvar t
    
    local lst "m1"
    forvalues i=2/12 {
      egen byte `t'=rowtotal(`lst')
      quietly count if `t'>0   // active in any of the previous months
      // ... do whatever else based on `t'>0
      display "`i' `r(N)'"
      drop `t'
      local lst "`lst' m`i'"
    }
    Produces:

    2 1
    3 2
    4 3
    5 3
    6 4
    7 4
    8 4
    9 4
    10 4
    11 4
    12 4

    Best, Sergiy Radyakin

    Tip for all the question posters: providing an input statement like above that creates a dataset resembling yours as part of your question greatly improves chances of getting a response.

    Comment


    • #3
      Sergiy gave an excellent answer. It's still true that your data structure is ill suited to most questions typical for your kind of data. I'd recommend reshape long.

      Comment


      • #4
        Here is what I did, following Sergiy's answer
        Reshape was too much trouble since I use an already heavy survey dataset

        (recall) I have a household businesses database. The aim was in fine to deseasonalize some performance variables (say, turnover), using self-evaluation of activity for each month.
        What I was trying to do was the first step, consisting in attributing max, mean and min values based on the reference period, which is the last month of non-0 activity (and can take value 1/2/3). Thus I had to attribute different values to my outcome variable and condition on what could be written "all variables of monthly activity indicator before the one for this month are equal to 0"
        Here is the loop that worked (although it might not win coding beauty contests)

        tempvar t
        local lst "month1"
        forvalues i=2/12 {
        egen byte `t'=rowtotal(`lst')
        replace camax=$varCA if month`i'==3 & `t'==0
        replace camin=camax/ratio if month`i'==3 & `t'==0
        replace camoy=(camax+camin)/2 if month`i'==3 & `t'==0

        replace camoy=$varCA if month`i'==2 & `t'==0
        replace camin=2*camoy/(1+ ratio) if month`i'==2 & `t'==0
        replace camax=2*ratio*camoy/(1+ratio) if month`i'==2 & `t'==0

        replace camin=$varCA if month`i'==1 & `t'==0
        replace camax=ratio*camin if month`i'==1 & `t'==0
        replace camoy=(1+ratio)*camin/2 if month`i'==1 & `t'==0

        drop `t'
        local lst "`lst' month`i'"
        }

        Comment

        Working...
        X