Announcement

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

  • Macro variable

    Hi,

    I would like to define a new macro variables with the same variables that are in a first macro variable defined formerly but each variable would have "r" at the beginning of the name. The following code illustrate what I'm trying to achieve.

    Code:
    sysuse auto, clear
    
    global var "headroom trunk weight length turn"
    
    foreach i in $var{
    gen r`i'= `i'*100
    }
    
    global rvar r$var /* this is wrong, but do not know how to code it */
    Note that I have many variables and I do not want to add manually an "r" at the beginning of each variable of the second global macro...

  • #2
    Code:
    global rvar: subinstr global var " " " r", all
    global rvar r$rvar
    That said, I strongly discourage the use of global macros. They are a dangerous coding practice and should be used only when a local macro absolutely can't do the job. That situation is quite rare in practice. I strongly suggest you do this with locals instead. Also it may be simpler to iteratively create rvar inside your loop:

    Code:
    local var headroom trunk weight length turn
    local rvar
    
    foreach v of varlist `var' {
        gen r`v' = 100*`v'
        local rvar `rvar' r`v'
    }
    display `"`rvar'"'

    Comment


    • #3
      For some characteristically pedantic comments on terminology here see also http://www.stata.com/statalist/archi.../msg01258.html

      Comment


      • #4
        Clyde,

        Thanks a lot for the code, that really helps!

        I agree with the "danger" of using global macros. However, using local macro forces to execute "local ..." every time one wants to test a piece of code which makes them unpractical. Is there any way to go around that?

        Comment


        • #5
          However, using local macro forces to execute "local ..." every time one wants to test a piece of code which makes them unpractical. Is there any way to go around that?
          Well, this is a problem only if you are running very long code files where the macros are defined at the top and used at the bottom. So the first step is to defer defining local macros until close to where they are used. If they are used repeatedly in a long file and you want to test only a segment near the end, you can just comment out the intervening material if that material is not required to create the right conditions for the code you are testing. In general, an economic coding style where do-files are short anyway, with complexity managed by calling other do- or ado- files, generally avoids having these difficulties in the first place.

          Another approach, which I use primarily when I want to reuse the same macros in several different do-files, is to create a separate do-file that defines those macros and does nothing else. I then use the -include- command to insert that code in the do-files at the point they are needed. You can use this same technique at multiple points in a long file just as easily. So it looks like:

          Code:
          // THIS GOES IN A DO FILE TO DEFINE MACROS
          local my_first_macro red blue green
          local my_second_macro Francois Clyde Nick
          local my_third_macro headroom length weight trunk
          // etc.
          // SAVE ALL THE ABOVE IN define_macros.do
          
          // THIS GOES IN YOUR REGULAR DO-FILES
          /* whatever*/
          // NEED TO USE MACROS HERE
          include define_macros
          // CODE THAT USES THESE MACROS HERE
          
          /* hundreds of lines of other code*/
          
          // NEED TO USE THOSE MACROS AGAIN AND DON'T WANT
          // TO RE-RUN THE WHOLE FILE TO TEST THIS PART
          include define_macros.do
          // CODE THAT USES THESE MACROS HERE
          Important: You cannot do this with -run- or -do-. The command must be -include-. The -include- command incorporates a "virtual" copy of the contents of the included file. It is equivalent to just copying and pasting, but can be invoked from within a do-file on the fly. That way, the macros in define_macros.do have been, in effect, defined within the including do-file and so have the usual scope extending for the remainder of the file. If you were to try -run- or -do- instead, then those macros would be defined during the execution of define_macros.do, and therefore they would go out of scope when control returns to the main do-file.

          Comment


          • #6
            Thanks a lot, that help!

            Comment

            Working...
            X