Announcement

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

  • List of locals

    Hi Statalist!

    I need to make a list of some locals defined in the .do file, in order to verify if there are (and eventually drop) double locals.
    How can I proceed?

    Thank you

  • #2
    Is this the right understanding of your situation? In the course of a relatively long do-file, you have occasion to create a large number of locals. At some later point in the code, it is possible that your code will create a new local with the same name as some existing local.

    If that is correct, I'd say there is likely something unusual about your programming approach, and I'd think that there would be a way to avoid the problem completely.

    Whether or not that is a correct understanding of your problem, I think we would need more detail about your code in order to help you. An example of code that illustrates the problem would be necessary, at least for me. I'm assuming that your code is long and complicated, but perhaps you can show some kind of small "toy" example.
    Last edited by Mike Lacy; 05 Feb 2020, 10:38.

    Comment


    • #3
      Code:
      macro list 
      shows the locals visible at any point.

      What is a double local? If I go

      Code:
      local foo "frog"
      and then

      Code:
      local foo "toad"
      the later definition overwrites the former definition. There was a good verb for this in English which I can't bring myself to use any more.

      Comment


      • #4
        Ok, this is what I am doing. I have some variables named b*. I need to use some of these b* variables (let's assume b*cc* and b*ch*) in a first time and all the other b* variables in a second time. I'm doing this for a large number of datasets, hence I have to be the more general it is possible.

        capture describe b*cc*
        if _rc == 0 {
        foreach var of varlist b*cc* {
        sum `var'
        return list
        local tot_bl1_`var'=r(sum) //I need to store in a local the total value of the variable of interest in the baseline scenario (tha's why tot_bl*)
        }
        }
        capture describe b*ch*
        if _rc == 0 {
        foreach var of varlist b*ch* {
        sum `var'
        return list
        local tot_bl1_`var'=r(sum)
        }
        }

        At this point, I have to do the sum of all the locals I have defined until now. Probably, but I'm not sure, I could use a command like:

        local sum_locals=sum(tot_*)

        In the second step of the analysis, I have to do the same thing for all the b* variables except b*cc and b*ch.
        In my mind, the simplest thing to do could be doing the process for all the b* variables (that I don't precisely know, because they could be not exactly the same in all the datasets):

        capture describe b*
        if _rc == 0 {
        foreach var of varlist b* {
        sum `var'
        return list
        local tot_bl2_`var'=r(sum)
        }
        }

        and then eliminate from the list of locals the ones for b*cc* and b*ch* variables.
        At this point, as before, summing the remaining locals.

        The problem of the double local arises because - to distinguish the various steps - I added a number after tot_bl* in the locals' name.
        At this point, I have a "tot_bl1_*" and a "tot_bl2_*" for all b*cc* and b*ch* variables.
        I'll need the number in a further step of the analysis, when I'll compare the locals of the various datasets (bl as the baseline, step1, step2, etc.).

        Thank you Nick for the command "macro list", it helps

        Comment


        • #5
          I still don't quite understand the duplication of names (give them longer names??), but one trick that might help with your more general problem is to create a local with a list of the relevant locals and then retrieving their values later, like this:

          Code:
          sysuse auto
          local loclist ""
          foreach v of varlist weight headroom foreign {
             quiet sum `v'
             local s_`v' = r(sum)  // save the value of interest in a local
             // Add name of this local to a list. Perhaps just putting its value into
             // a list would work for you.
             local loclist `loclist' s_`v' 
          }
          macro list  // check it out
          // Retrieve the value of each local in the list
          foreach L in `loclist' {
            di "contents of `L': ``L''" 
          }
          I just have one local list here, but you could have one for each dataset, i.e. loclist1, loclist2, .... , keep track of how many such lists you have, and then loop over them at the end.
          Code:
          forval i = 1/`NumberOfLists' {
             do something with loclist`i'
          }
          As for eliminating variables names from some list, you could use the list "subtraction" function described at -help macro lists-, e.g. local trimlist: ThisList - ThatList


          Comment


          • #6
            I would not use locals for this. This is a good application of scalars.

            Code:
            scalar sum = 0 
            
            foreach v of var b*ch* { 
                  su `v', meanonly 
                  scalar sum = scalar(sum) + r(sum) 
            }
            Also, consider Mata here. Here is a very silly example:

            Code:
            . sysuse auto, clear
            (1978 Automobile Data)
            
            . mata
            ------------------------------------------------- mata (type end to exit) ------------------------------
            : st_view(x = ., ., ("turn trunk"))
            
            : x
                     1    2
                 +-----------+
               1 |  40   11  |
               2 |  40   11  |
               3 |  35   12  |
               4 |  40   16  |
               5 |  43   20  |
               6 |  43   21  |
               7 |  34   10  |
               8 |  42   16  |
               9 |  43   17  |
              10 |  42   13  |
              11 |  44   20  |
              12 |  43   16  |
              13 |  45   13  |
              14 |  34    9  |
              15 |  43   20  |
              16 |  31   17  |
              17 |  41   16  |
              18 |  40    7  |
              19 |  43   13  |
              20 |  35    8  |
              21 |  46   17  |
              22 |  46   17  |
              23 |  46   21  |
              24 |  33    9  |
              25 |  43   10  |
              26 |  51   22  |
              27 |  48   18  |
              28 |  41   15  |
              29 |  39    9  |
              30 |  48   16  |
              31 |  44   23  |
              32 |  41   15  |
              33 |  45   16  |
              34 |  43   17  |
              35 |  43   20  |
              36 |  42   16  |
              37 |  42   16  |
              38 |  42   20  |
              39 |  43   14  |
              40 |  40   10  |
              41 |  43   17  |
              42 |  37   11  |
              43 |  37   11  |
              44 |  36   17  |
              45 |  38    8  |
              46 |  44   16  |
              47 |  42   20  |
              48 |  42    7  |
              49 |  45   16  |
              50 |  40   17  |
              51 |  43   13  |
              52 |  41    7  |
              53 |  37   15  |
              54 |  36   11  |
              55 |  34   12  |
              56 |  35    6  |
              57 |  32    8  |
              58 |  34    8  |
              59 |  38    8  |
              60 |  36   16  |
              61 |  36   10  |
              62 |  34    5  |
              63 |  33   11  |
              64 |  38   14  |
              65 |  34   10  |
              66 |  36   11  |
              67 |  36   14  |
              68 |  35    9  |
              69 |  36   11  |
              70 |  36   12  |
              71 |  35   15  |
              72 |  35   15  |
              73 |  36   16  |
              74 |  37   14  |
                 +-----------+
            
            : sum(x)
              3952
            
            : sum(x[,1])
              2934
            
            : sum(x[,2])
              1018

            Comment


            • #7
              Hi Thank you for your suggestions!

              I tried both locals and scalars, but at the end I thinl I'll continue to use locals.
              In this case, I have some lists of locals (10 for each dataset).

              Let's consider the list bl_kidfam (the name means: baseline scenario, children support, family benefits), which contains the locals:
              - sum_bl_bch (total value in the baseline scenario of children benefits);
              - sum_bl_bcc (total value in the baseline scenario of child-care benefits);
              - sum_bl_bfa (total value in the baseline scenario of other family benefits).

              Now, I want to calculate the total government spending in child-support family benefits - that is, the sum of the sums of each variable (bch, bcc, and bfa).

              local sum_bl_kidfam = sum(...)

              surely won't work. What can I do to sum the value of all the elements of a list?

              Comment


              • #8
                No such function sum() exists that can be applied that way The underlying point is that locals are really holders for text. There is no real gain in thinking up syntax you would like to exist. You have to work from what Stata provides.

                If you are determined to go that way, you need to loop over locals and add each sum to the sum so far.

                Comment


                • #9
                  Ok... In the case I use scalars, I'll have a sort of vector, is it?

                  Comment


                  • #10
                    You want a sum of sums, so if you like a vector is tacit. I can't see that you need to use one.

                    Comment

                    Working...
                    X