Announcement

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

  • -Macro shift- for a local macro

    Is there a way to perform the equivalent of a -macro shift- on a local macro, rather than on the numbered macros (`1',`2'...)? That is, I would like to remove the first (or last) element of a macro list without knowing its value.

  • #2
    yes, see "macro shift" under "help macro" - however, little info is given there but the following, and more, can be found in the manual (linked from the help file):
    Sometimes programs have in a macro a list of things—numbers, variable names, etc.—that you wish
    to access one at a time. For instance, after parsing (see [U] 18.4 Program arguments), you might have
    in the local macro ‘varlist’ a list of variable names. The tokenize command (see [P] tokenize) will
    take any macro containing a list and assign the elements to local macros named ‘1’, ‘2’, and so on.
    That is, if ‘varlist’ contained “mpg weight displ”, then coding
    tokenize ‘varlist’
    will make ‘1’ contain “mpg”, ‘2’ contain “weight”, ‘3’ contain “displ”, and ‘4’ contain “ ” (nothing).
    The empty fourth macro marks the end of the list.
    macro shift can be used to work through these elements one at a time in constructs like
    while ”‘1’” != ”” {
    do something based on ‘1’
    macro shift
    }
    macro shift discards ‘1’, shifts ‘2’ to ‘1’, ‘3’ to ‘2’, and so on. For instance, in our example, after
    the first macro shift, ‘1’ will contain “weight”, ‘2’ will contain “displ”, and ‘3’ will contain “ ”
    (nothing).
    It is better to avoid macro shift and instead code
    local i = 1
    while ”‘‘i’’” != ”” {
    do something based on ‘‘i’’
    local i = ‘i’ + 1
    }
    This second approach has the advantage that it is faster. Also what is in ‘1’, ‘2’, . . . remains unchanged
    so that you can pass through the list multiple times without resetting it (coding “tokenize ‘varlist’”
    again).

    Comment


    • #3
      What defines an element in your case? Is it a word, i.e. elements are separated by a space, or is it a list of macros and an element can be whatever is in those macros?
      ---------------------------------
      Maarten L. Buis
      University of Konstanz
      Department of history and sociology
      box 40
      78457 Konstanz
      Germany
      http://www.maartenbuis.nl
      ---------------------------------

      Comment


      • #4
        I want to run a regression multiple times, deleting one RHS varaible with each run. So it is a list of variable names, and it looks like -tokenize- is just what I need to keep it simple. Thanks.

        Comment


        • #5
          That sounds like

          Code:
          sysuse auto, clear 
          
          local X length weight displacement 
          
          foreach v of local X { 
              local x : list X - v 
              di 
              di "{title: `x'}"
              regress mpg `x'
              di 
          }

          Comment


          • #6
            #5 drops one RHS variable each time, always keeping two. My own interpretation was that OP wanted nested models, successively dropping an additional RHS variable each time. So perhaps this instead:
            Code:
            sysuse auto, clear
            
            local X length weight displacement
            
            while "`X'" ~= "" {
                di
                di "{title: `X'}"
                regress mpg `X'
                di
                local v: word 1 of `X'
                local X: list X - v
            }
            Last edited by Hemanshu Kumar; 29 Jul 2025, 08:38.

            Comment


            • #7
              https://www.stata.com/manuals/pgettoken.pdf

              Comment


              • #8
                Originally posted by Hemanshu Kumar View Post
                #5 drops one RHS variable each time, always keeping two. My own interpretation was that OP wanted nested models, successively dropping an additional RHS variable each time.
                Well, that would be the equivalent of adding one variable at a time, which is simply
                Code:
                foreach x in length weight displacement {
                    local X `X' `x'
                    regress mpg `X'
                }

                Comment


                • #9
                  Well, that would be the equivalent of adding one variable at a time,...
                  Well, in a sense, yes, but practically, perhaps not. If it is important to assure that the same estimation sample is used for all of the regressions, and there are missing values to reckon with, then adding one at a time as in #8 will fail. At the very least, the model with the full set of variables would need to be run first and its estimation sample imposed on the others when they are run. But if we're going to do that, it's simpler to just remove one at a time, as several others have shown how to do.

                  Comment


                  • #10
                    Originally posted by Clyde Schechter View Post
                    Well, in a sense, yes, but practically, perhaps not. If it is important to assure that the same estimation sample is used for all of the regressions, and there are missing values to reckon with, then adding one at a time as in #8 will fail.
                    Fair enough; so will all other specific code suggestions so far.

                    Comment


                    • #11
                      Originally posted by Clyde Schechter View Post
                      Well, in a sense, yes, but practically, perhaps not. If it is important to assure that the same estimation sample is used for all of the regressions, and there are missing values to reckon with, then adding one at a time as in #8 will fail.
                      Using mark and markout would solve this (however, be sure to specify the markout variable generated by mark as the first variable after markout, otherwise you could inadvertently mess up your data!). Compare version 1 and version 2:
                      Code:
                      cap which estout  // for regression tables (incl. -esttab-) 
                      if _rc ssc install estout 
                       
                      sysuse auto, clear  
                       
                      * ------------------------------------------------------------------------------ 
                      // Version 1: 
                       
                      cap est drop * 
                      local X = "" 
                       
                      local runs = 0 
                      foreach x in length rep78 displacement { 
                          local ++runs 
                          local X `X' `x' 
                          qui regress mpg `X' 
                          est sto m`runs' 
                      } 
                      esttab m* 
                       
                      * ------------------------------------------------------------------------------ 
                      // Version 2: 
                       
                      local vars length rep78 displacement 
                      cap drop valid 
                      mark valid 
                      markout valid `vars' 
                       
                      cap est drop * 
                      local X = "" 
                       
                      local runs = 0 
                      foreach x in `vars' { 
                          local ++runs 
                          local X `X' `x' 
                          qui regress mpg `X' if valid 
                          est sto m`runs' 
                      } 
                      esttab m*

                      Comment


                      • #12
                        Addendum to #11:

                        I don't know how the question in #4 is motivated, but if the aim is a variant of stepwise regression be aware of its issues, see https://www.stata.com/support/faqs/s...sion-problems/ (which Daniel Feenberg is most likely aware of).

                        Comment

                        Working...
                        X