Announcement

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

  • iterating through a list at the same time as a loop

    I am looking if there is a way to code a forvalues loop to perform 2 distinct tasks. Specifically, I have a forvalues loop that loops every 4 years (forvalues 1992 (4) 2016)) from 1992 to 2016. I would also like to iterate up a letter of the alphabet each time the loop reiterates. So, for example, when the loop goes through the 1st time (1992), it would assign a second variable with an A, and the 2nd time (1996) it would use the letter B. I am hoping that I could identify a group of elements (such as the alphabet or even specific titles) in a local macro that would iterate at the same time as the loop. (This is different than just nesting loops).

    This is for multiple tables that I have to label with a letter of the Alphabet and the date (Panel A: 1992). Below is the code that I have been working with:

    local k = "replace" // the first iteration needs to be replace, append thereafter
    forvalues i = 1992 (4) 2016{

    preserve
    mkmat p_4Greenp p_4Greenn p_4Purplep p_4Purplen, matrix(e_pval) // makes a 21 by 4 marix with the p values,
    putdocx clear
    putdocx begin, font(times new roman, "12")
    putdocx paragraph, spacing(after,0pt) halign(left)
    putdocx text ("Panel A: `i'") // this is where I'd like the loop to include a 2nd action in the loop to iterate from A through G
    rename (window) (Window)
    replace Window = "1 year" if Window == "(0,+11)"
    replace Window = "2 years" if Window == "(0,+23)"
    replace Window = "3 years" if Window == "(0,+35)"
    putdocx table retwin`i' = data(Window Greenp Greenn Purplep Purplen) if year == `i', varnames border(top) border(bottom) border (left, nil) border(right, nil) width(6.0in)

    local m = 1 // this is for the column in the e_pval (pvalues) matrix. Should move over 1 per iteration.
    forvalues n = 2/5 { // opens the first loop that goes through the columns in the returns tables.

    local p = 2 // goes over the row of the return table. Has to be outside the beginning of the loop else it will always reset back to 2
    forvalues q = 1/3 { // the rows for the e_pval matrix
    putdocx table retwin`i'(`p',`n') = (""),append
    local ++p
    }

    local ++m
    }

    putdocx save d:\Documents\table.docx, `k' // switching replace with append.
    restore
    local k = "append"
    }

    The variables are portfolio returns (Greenp, Greenn, Purplep, Purplen) and the p values (p_4Greenp, p_4Greenn, etc.).

    I have been able to get something to work by generating a new variable that moves up with the loop but this seems very inelegant and only works by adding a new variable each time instead of a local macro:
    gen alpha = "A"
    replace alpha = "B" if year == 1996
    replace alpha = "C" if year == 2000
    replace alpha = "D" if year == 2004
    replace alpha = "E" if year == 2008
    replace alpha = "F" if year == 2012
    replace alpha = "G" if year == 2016

    Anyway, if anyone has an idea on how to do this (and the stamina to look through someone else's code), I would be very grateful. I hope I (and my code) is clear enough.

  • #2



    Here's where I learned about a pretty standard approach to this:
    https://www.stata.com/support/faqs/p...arallel-lists/

    Translated to your situation, this could be:
    Code:
    local letters = strupper(c(alpha))
    local pos = 1
    forvalues i = 1992 (4) 2016 {
      local c: word `pos' of `letters'
      di "`c'"
      local ++pos
    }
    Here's a more specific and hack-ish solution:
    Code:
    local asciipos = 65 // ascii code for "A"
    forvalues i = 1992 (4) 2016 {
      di char(`asciipos')
      local ++asciipos
    }

    Comment


    • #3
      Consider these examples:

      Code:
      . di word("A B C D E F G", (1992 - 1988) / 4)
      A
      
      . di word("A B C D E F G", (2016 - 1988) / 4)
      G
      
      . di word(c(ALPHA) ,  (2092- 1988) / 4)
      Z
      So you don't need a loop at all. An answer is

      Code:
      gen alpha = word(c(ALPHA), (year - 1988) ./ 4)
      for a variable and similarly a single expression for a single year value.


      Comment


      • #4
        So, I think you want


        Code:
        local show = word(c(ALPHA), (`i' - 1988) / 4) 
        putdocx text ("Panel `show': `i'")
        You could do that in one line, not two, but at some cost to clarity.

        Comment


        • #5
          Thank you both so much! I appreciate the time you spent looking at this and helping with the code. I have updated it trying both suggestions and they both work great.

          Comment

          Working...
          X