Announcement

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

  • Issues with display of global macro contents within foreach

    Hi there I am using Stata/BE 17,

    I am having issues displaying the contents of a global macro that I generate using a loop. Instead, what displays is the last reference from my last global references in the loop. The loop is working and I can successfully access the contents of the global macro if I type display "$full macro name" after the loop is completed.

    Example:

    Code:
    /*creating global macros for following foreach loop*/
    global types "t1 t2 t3 t4 t5 t6 t7 t8 t9"
    global wings_t1 "w2 w9"
    global wings_t2 "w1 w3"
    global wings_t3 "w2 w4"
    global wings_t4 "w3 w5"
    global wings_t5 "w4 w6"
    global wings_t6 "w5 w7"
    global wings_t7 "w6 w8"
    global wings_t8 "w7 w9"
    global wings_t9 "w8 w1"
    
    /*loop and create global for each type by wing*/
    foreach t of global types {
        foreach w of global wings_`t' {
                global `t'_`w' "`t'_`w'_1 `t'_`w'_2 `t'_`w'_3 `t'_`w'_4 `t'_`w'_5 `t'_`w'_6 `t'_`w'_7 `t'_`w'_8"
               display "$`t'_`w'"
     }
    }
    My results are as follows from the above loop:

    Code:
    w2
    w9
    w1
    w3
    w2
    w4
    w3
    w5
    w4
    w6
    w5
    w7
    w6
    w8
    w7
    w9
    w8
    w1
    However, if I type any of the potential combinations for the lists I created, I can obtain the correct results:

    Code:
    display "$t9_w8"
    t9_w8_1 t9_w8_2 t9_w8_3 t9_w8_4 t9_w8_5 t9_w8_6 t9_w8_7 t9_w8_8
    I would like to loop through a factor analysis for each typexwing combination using the created macro lists, but when I attempt to I get the error related to the incorrect display (e.g., variable w2 not found). The full code would look something like:

    Code:
    foreach t of global types {
        foreach w of global wings_`t' {
                global `t'_`w' "`t'_`w'_1 `t'_`w'_2 `t'_`w'_3 `t'_`w'_4 `t'_`w'_5 `t'_`w'_6 `t'_`w'_7 `t'_`w'_8"
                display "$`t'_`w'"
                factor $`t'_`w', mineigen(1) blanks(.30)  ipf
                rotate, oblimin(0) kaiser  blanks(.30)
                screeplot, name(`t'_`w') title(`t'_`w')
                 sortl
     }
    }
    but results in:

    Code:
    . foreach t of global types {
      2.         foreach w of global wings_`t' {
      3.                         global `t'_`w' "`t'_`w'_1 `t'_`w'_2 `t'_`w'_3 `t'_`w'_4 `t'_`w'_5 `t'_`w'_6 `t'_`w'_7 `t'_`w'_8"
      4.                         display "$`t'_`w'"
      5.             factor $`t'_`w', mineigen(1) blanks(.30)  ipf
      6.                 rotate, oblimin(0) kaiser  blanks(.30)
      7.                         screeplot, name(`t'_`w') title(`t'_`w')
      8.                 sortl
      9.  }
     10. }
    w2
    variable w2 not found
    r(111);
    I have sleuthed and sleuthed, but I may be using incorrect terminology since I am new to Stata. Any help is greatly appreciated. Thanks!
    Last edited by Ashleigh Hope; 25 Sep 2023, 13:11.

  • #2
    maybe use macro list

    help macro

    Comment


    • #3
      Yes, I can see the correct contents that way also, but this still doesn't solve the problem of looping through the factor analysis. There's an issue with the reference within the loop that still prevents me using those newly generated macro variables for 18 factor analyses for the 18 groups (type by wing). Any thoughts on the second, but related problem?

      Comment


      • #4
        Code:
        display "$`t'_`w'"
        
        // SHOULD BE
        
        display "${`t'_`w'"}
        The problem airses because in -display "$`t'_`w'"-, Stata doesn't have explicit information about how much of `t'_`w' is part of the intended name of the global macro you want displayed. By enclosing it in curly braces, you disambiguate the possibilities. Without that, it thinks you want to display global $`t'_, which does not exist and hence is treated as an empty string, followed by `w', which does. So only `w' gets displayed in the Results window.

        The exact same problem arises in your -factor $`t'_`w'- command. -factor ${`t'_`w'}- will, similarly, resolve the problem.

        By the way, there is no reason to use global macros for any of this, and your code would be safer if you replaced all of them by local macros.

        Added: Crossed with #3.

        Last edited by Clyde Schechter; 25 Sep 2023, 13:38.

        Comment


        • #5
          I think the problem is the incorrect use of macros and combining global and local

          Explicitly,
          change
          display "$`t'_`w'"
          with
          display "${`t'_`w'}"


          and do so in your code too. You will see the difference.

          The problem. If you combine Globals with locals, its necessary for you to use Curly brackets.
          F

          Comment


          • #6
            Thank you, Clyde! I think I just like being able to run line by line with global macros and the ability to reference again and again, but there is probably more potential for error (as I am assuming based on your comment) that I am missing as a new user. I appreciate the help, greatly!

            The following ended up working(albeit I still haven't updated with locals and will do moving forward).

            Code:
            foreach t of global types {
                foreach w of global wings_`t' {
                        global `t'_`w' "`t'_`w'_1 `t'_`w'_2 `t'_`w'_3 `t'_`w'_4 `t'_`w'_5 `t'_`w'_6 `t'_`w'_7 `t'_`w'_8"
                        display "${`t'_`w'}"
                asdoc      factor ${`t'_`w'}, mineigen(1) blanks(.0)  ipf save(filepath/wings_results.doc)
            asdoc        rotate, oblimin(0) kaiser  blanks(.0) 
                        screeplot, name(`t'_`w') title(`t'_`w') saving("filepath/`t'_`w'", replace)
            asdoc        sortl        
             }
            }

            Comment

            Working...
            X