Announcement

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

  • Question about creating a global variable list.

    Dear Stata Community,

    I am trying to use a global variable list definition in a collapse, but I have run into a problem. In my "main" do file I define a variable list (of all state-level variables, excluding the industry code and the year) as follows:

    ds, has(type numeric)
    local vars `r(varlist)'
    local remove "year industry"
    global my_state_vars: list vars - remove
    di "`my_state_vars'"

    later in the do file I call another do file in which the following commands appear:

    foreach x of global my_state_vars {
    replace `x' = 0 if `x' == .
    }

    collapse (sum) `my_state_vars', by(year region industry)

    What puzzles me is that the loop, the replace, works fine, though the collapse returns a "varlist required".

    This is my first attempt at using a global varlist, so I may be missing something simple. Thank you for your help,

    Michael Anderson




  • #2
    I think you are mixing up locals and globals

    Code:
    collapse (sum) $my_state_vars, by(year company)
    The experienced users here will tell you that using globals is not a good idea. So, I would recommend replacing

    Code:
    global my_state_vars: list vars - remove
    with

    Code:
    local my_state_vars: list vars - remove

    Comment


    • #3
      A few comments.

      It is not clear why this code in post #1 worked.
      Code:
      global my_state_vars: list vars - remove
      di "`my_state_vars'"
      when the second command should have been
      Code:
      di "$my_state_vars"
      to display the global macro. Perhaps you had previously create a local macro named my_state_vars and it was still in memory.

      The collapse command excludes missing values from its calculations, so collapse applied to a variable with missing values will be apply the requested function to only nonmissing values.
      Code:
      . clear
      
      . input float x
      
                   x
        1. 1
        2. 2
        3. .
        4. 4
        5. 5
        6. end
      
      . collapse (sum) x
      
      . list, noobs
      
        +----+
        |  x |
        |----|
        | 12 |
        +----+
      
      .
      And thus in the code in post #1, the foreach loop before the collapse has no effect and can be omitted.

      In post #2. I think Andrew overlooked the statement that the collapse command exists in another do-file, so to pass the variable names in a macro, a global macro is required.

      However, it is instead possible to pass arguments to a do-file on the do command. In the example below, I first created a trivial do-file to summarize a list of variables. I then run the do-file with three variable names on the do command.
      Code:
      . sysuse auto, clear
      (1978 Automobile Data)
      
      . type do1.do
      display "this is the first argument - `1'"
      display "this is all the arguments - `0'"
      summarize `0'
      
      . do do1 weight length price
      
      . display "this is the first argument - `1'"
      this is the first argument - weight
      
      . display "this is all the arguments - `0'"
      this is all the arguments - weight length price
      
      . summarize `0'
      
          Variable |        Obs        Mean    Std. Dev.       Min        Max
      -------------+---------------------------------------------------------
            weight |         74    3019.459    777.1936       1760       4840
            length |         74    187.9324    22.26634        142        233
             price |         74    6165.257    2949.496       3291      15906
      
      .
      And I could have run the do-file with arguments stored in a local macro (such as the result of your : list vars - remove).
      Code:
      local vars weight length price
      do do1 `vars'

      Comment


      • #4
        The code in #1 can be slimmed down:

        Here is the original:

        Code:
        ds, has(type numeric)
        local vars `r(varlist)' 
        local remove "year industry"
        global my_state_vars: list vars - remove
        di "`my_state_vars'" 
        
        foreach x of global my_state_vars {
        replace `x' = 0 if `x' == .
        }
        Here is a slimmed-down version:

        Code:
        ds year industry, not
        ds `r(varlist)', has(type numeric)
        global my_state_vars `r(varlist)' 
        mvencode $my_state_vars, mv(0)




        Comment


        • #5
          Dear Andrew, William, and Nick,

          *Thank you* for this helpful advice, which I have taken. I've substituted a local macro for the global, and I appreciate also learning how to tighten up my code. I may come back with a question about how to pass `my_vars' to a do file called within the main do file, still working on that. But the do file is now working, and I really appreciate the help.

          Stata is a wonderful program, but it gives up its secrets reluctantly, and it really is great to have such a helpful community.

          Michael

          Comment

          Working...
          X