Announcement

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

  • how to get foreach of varlist v1-v10 take every second variable from the specified set (v1 v3 v5...)?

    Hi dear Statalisters,
    I was wondering if there is any way to get Stata to pick every second variable of a specified list in varlist of a loop command?
    Specifically, I would like to use -foreach of varlist-, but indicate stata to skip every second var and take the first, third, fifth and so on.. from the list.
    Is there any smart way to do it?
    Many thanks for any suggestions!

  • #2
    Every second variable sounds like v2 v4 v6 v8 v10 to me, but I will run with your interpretation.

    Code:
    foreach v in v1 v3 v5 v7 v9 { 
           * whatever with `v'  
    }
    is fine by me, as is

    Code:
     
    forval j = 1(2)9 { 
           * whatever with v`j' 
    }

    In the unlikely but not impossible event that I get to grade Stata code, either gets an A from me as clear and concise and direct.

    Code:
    unab myvars : v1-v10 
    tokenize `myvars' 
    
    forval j = 1(2)9 { 
          * whatever with ``j''' 
    }
    might get a B for being too complicated if the variable names really were v1 to v10. But if the names were an arbitrary mess, it is closer to generality.

    Comment


    • #3
      ok, I have found a solution by using -findname- to generate the desired varlist. I was lucky enough that my vars all had value labels with "Y" and all those I wanted to discard of from the list did not have the letter Y, so I simply used findname, vall(*Y*) local(varlist). But this solution is not very robust. Had I "Y"s in vallabs in the other set of vars the problem would remain

      Comment


      • #4
        findname is from the Stata Journal and familiar to me.

        I'd need more concrete details to suggest other solutions.


        Comment


        • #5
          Thank you Nick for a reply! In trying to be general I realize now that I misspecified my problem. Had it been so easy I would've never asked. My varnames are in fact as follows

          ANONID UF01_7MSC UF03_10_2D UF05_10_4D UF08_7ROK UF10_10_2M UF12_10_4M TN36_3M2
          VB06_YR UF01_10_1R UF03_10_3R UF05_10_5R UF08_7MSC UF10_10_2D UF12_10_4D TJ01_START~R
          VB06_MTH UF01_10_1M UF03_10_3M UF05_10_5M UF08_10_1R UF10_10_3R UF12_10_5R TJ01_START~H
          VC01YR UF01_10_1D UF03_10_3D UF05_10_5D UF08_10_1M UF10_10_3M UF12_10_5M TJ01_ENDYEAR
          VC01MTH UF01_10_2R UF03_10_4R UF06_3ROK UF08_10_1D UF10_10_3D UF12_10_5D TJ01_ENDMO~H
          VD05_YR UF01_10_2M UF03_10_4M UF06_3MSC UF08_10_2R UF10_10_4R TJ00_START~R TJ02_START~R
          VD05_MTH UF01_10_2D UF03_10_4D UF06_7ROK UF08_10_2M UF10_10_4M TJ00_START~H TJ02_START~H
          VD15_YR UF01_10_3R UF03_10_5R UF06_7MSC UF08_10_2D UF10_10_4D TJ00_ENDYEAR TJ02_ENDYEAR
          VD15_MTH UF01_10_3M UF03_10_5M UF06_10_1R UF08_10_3R UF10_10_5R TJ00_ENDMO~H TJ02_ENDMO~H
          VE11A_YB UF01_10_3D UF03_10_5D UF06_10_1M UF08_10_3M UF10_10_5M TG20_01R1 TJ03_START~R
          VE11A_MB UF01_10_4R UF04_3ROK UF06_10_1D UF08_10_3D UF10_10_5D TG20_01M1 TJ03_START~H
          VE11A_YE UF01_10_4M UF04_3MSC UF06_10_2R UF08_10_4R UF11_3ROK TG20_01R2 TJ03_ENDYEAR
          VE11A_ME UF01_10_4D UF04_7ROK UF06_10_2M UF08_10_4M UF11_3MSC TG20_01M2 TJ03_ENDMO~H
          VE11B_YB UF01_10_5R UF04_7MSC UF06_10_2D UF08_10_4D UF11_7ROK TG20_02R1 TJ04_START~R
          VE11B_MB UF01_10_5M UF04_10_1R UF06_10_3R UF08_10_5R UF11_7MSC TG20_02M1 TJ04_START~H
          VE11B_YE UF01_10_5D UF04_10_1M UF06_10_3M UF08_10_5M UF11_10_1R TG20_02R2 TJ04_ENDYEAR
          VE11B_ME UF02_3ROK UF04_10_1D UF06_10_3D UF08_10_5D UF11_10_1M TG20_02M2 TJ04_ENDMO~H
          VE11C_YB UF02_3MSC UF04_10_2R UF06_10_4R UF09_3ROK UF11_10_1D TG20_03R1 TJ05_START~R
          VE11C_MB UF02_7ROK UF04_10_2M UF06_10_4M UF09_3MSC UF11_10_2R TG20_03M1 TJ05_START~H
          VE11C_YE UF02_7MSC UF04_10_2D UF06_10_4D UF09_7ROK UF11_10_2M TG20_03R2 TJ05_ENDYEAR
          VE11C_ME UF02_10_1R UF04_10_3R UF06_10_5R UF09_7MSC UF11_10_2D TG20_03M2 TJ05_ENDMO~H
          VF03_4YR UF02_10_1M UF04_10_3M UF06_10_5M UF09_10_1R UF11_10_3R TG20_04R1 TJ06_START~R
          VF03_4M UF02_10_1D UF04_10_3D UF06_10_5D UF09_10_1M UF11_10_3M TG20_04M1 TJ06_START~H
          VF03_7YR UF02_10_2R UF04_10_4R UF07_3ROK UF09_10_1D UF11_10_3D TG20_04R2 TJ06_ENDYEAR
          VF03_7M UF02_10_2M UF04_10_4M UF07_3MSC UF09_10_2R UF11_10_4R TG20_04M2 TJ06_ENDMO~H
          VF04_4YR UF02_10_2D UF04_10_4D UF07_7ROK UF09_10_2M UF11_10_4M TG20_05R1 TJ07_START~R
          VF04_4M UF02_10_3R UF04_10_5R UF07_7MSC UF09_10_2D UF11_10_4D TG20_05M1 TJ07_START~H
          VF04_7YR UF02_10_3M UF04_10_5M UF07_10_1R UF09_10_3R UF11_10_5R TG20_05R2 TJ07_ENDYEAR
          VF04_7M UF02_10_3D UF04_10_5D UF07_10_1M UF09_10_3M UF11_10_5M TG20_05M2 TJ07_ENDMO~H
          VF05_4YR UF02_10_4R UF05_3ROK UF07_10_1D UF09_10_3D UF11_10_5D TG20_06R1 TJ08_START~R
          VF05_4M UF02_10_4M UF05_3MSC UF07_10_2R UF09_10_4R UF12_3ROK TG20_06M1 TJ08_START~H
          VF03C7YR UF02_10_4D UF05_7ROK UF07_10_2M UF09_10_4M UF12_3MSC TG20_06R2 TJ08_ENDYEAR
          VF05_7M UF02_10_5R UF05_7MSC UF07_10_2D UF09_10_4D UF12_7ROK TG20_06M2 TJ08_ENDMO~H
          VF06_4YR UF02_10_5M UF05_10_1R UF07_10_3R UF09_10_5R UF12_7MSC TN36_1R1 TJ09_START~R
          VF06_4M UF02_10_5D UF05_10_1M UF07_10_3M UF09_10_5M UF12_10_1R TN36_1M1 TJ09_START~H
          VF06_7YR UF03_3ROK UF05_10_1D UF07_10_3D UF09_10_5D UF12_10_1M TN36_1R2 TJ09_ENDYEAR
          VF06_7M UF03_3MSC UF05_10_2R UF07_10_4R UF10_3ROK UF12_10_1D TN36_1M2 TJ09_ENDMO~H
          VF07_4YR UF03_7ROK UF05_10_2M UF07_10_4M UF10_3MSC UF12_10_2R TN36_2R1
          VF07_4M UF03_7MSC UF05_10_2D UF07_10_4D UF10_7ROK UF12_10_2M TN36_2M1
          VF07_7YR UF03_10_1R UF05_10_3R UF07_10_5R UF10_7MSC UF12_10_2D TN36_2R2
          VF07_7M UF03_10_1M UF05_10_3M UF07_10_5M UF10_10_1R UF12_10_3R TN36_2M2
          UF01_3ROK UF03_10_1D UF05_10_3D UF07_10_5D UF10_10_1M UF12_10_3M TN36_3R1
          UF01_3MSC UF03_10_2R UF05_10_4R UF08_3ROK UF10_10_1D UF12_10_3D TN36_3M1
          UF01_7ROK UF03_10_2M UF05_10_4M UF08_3MSC UF10_10_2R UF12_10_4R TN36_3R2

          and I need to use only the "year" var (from each pair of two consecutive vars) in the foreach loop. I was in fact too lazy to pick the vars by hand (but I realize now that with all the search & effort to find an intelligent solution I spent more time than I would've by applying mundane clicking :D) In fact as you posted I was typing my own answer with a roundabout solution, which is

          findname VB06_YR- TJ09_ENDMONTH, vall(*Y* *R*) local(varlist)

          BUT I would still generally be interested if such "skipping" vars in varlist is possible in stata (analogously to forvals with "(n)" - I know that forvals actually counts the numbers and not generates a priori a list of them, so it is straightforward with forvals. Still I am interested in possibilities with varlist

          Best regards + many thanks for the findname command!

          Comment


          • #6

            Code:
            foreach v of var *YR {
            
            }
            may help.

            Comment


            • #7
              Re #5

              Here is how I would choose alternating elements from a variable list when there was no apparent pattern.
              Code:
              . ds
              id  a   b   c   d   e   f   g   h   i   j
              
              . ds a-j
              a  b  c  d  e  f  g  h  i  j
              
              . local vars `r(varlist)'
              
              . forvalues w=1(2)`: word count `vars'' {
                2.         local v : word `w' of `vars'
                3.         display "Do something with variable `v'"
                4. }
              Do something with variable a
              Do something with variable c
              Do something with variable e
              Do something with variable g
              Do something with variable i
              
              .

              Comment


              • #8
                Many thanks for your suggestions, William's code does the job!

                Comment


                • #9
                  Code:
                  forvalues w=1(2)`: word count `vars'' {
                  I don't understand the codition used to iterate the loop.Can you explain a bit? @William Lisowski

                  Comment


                  • #10
                    Code:
                    . local gooddogs "Pitbull Chihuahua Bulterrier"
                    
                    . local howmany : word count `gooddogs'
                    
                    . dis `howmany'
                    3
                    So basically w goes from 1, in steps of 2, to the total number of words in the string.

                    Originally posted by Navjot Singh View Post
                    Code:
                    forvalues w=1(2)`: word count `vars'' {
                    I don't understand the codition used to iterate the loop.Can you explain a bit? @William Lisowski

                    Comment


                    • #11
                      To Joro's example we can add
                      Code:
                      . display `: word count `gooddogs''
                      3
                      which demonstrates the "expansion operator" syntax show in the output of help local as
                      Code:
                        [...] `expansion_optr' [...]
                      
                      
                          where expansion_optr is
                      
                              lclname | ++lclname | lclname++ | --lclname | lclname-- | =exp | :macro_fcn | .class_directive | macval(lclname)
                      so
                      Code:
                      . display `: word count `gooddogs''
                      does in one step what
                      Code:
                      local howmany : word count `gooddogs'
                      display `howmany'
                      does in two steps.

                      Comment


                      • #12
                        Blindly picking every second variable is dangerous because the code depends on the exact order of variables and is unlikely to throw errors when that order is not as expected. An alternative, more explicit, yet equally general solution is something along the lines:

                        Code:
                        foreach var of varlist * {
                            if any_property_of `var' {
                            
                            }
                            else {
                            
                            }
                        }
                        Edit: btw., this is exactly what findname (or ds) do to select the desired set of variables.
                        Last edited by daniel klein; 06 Sep 2020, 08:44.

                        Comment

                        Working...
                        X