Announcement

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

  • Reorder multiple numbered variables (stub ending) sequentially and make them alternate

    I'm using Stata 14 and have a seemingly simple question about order the variables in my list. I have multiple variables that are tagged with numbered stubs at the end. I'd like to order these variables so that they alternate. For instance, if I have the two variables 'districtX' and 'perhundistrictX', where X represents 1, 2, 3, ..., X, I'd like this:

    district1
    perhundistrict1
    district2
    perhundistrict2
    district3
    perhundistrict3

    rather than this:

    district1
    district2
    district3
    perhundistrict1
    perhundistrict2
    perhundistrict3

    I'm hoping to avoid having to type out all variables by total numbered stubs, N X 59.

    Any help is appreciated.

  • #2
    I think that the "sequential" option to the order command should do this; see "h order"

    Comment


    • #3
      The sequential option actually gives me the second output above. I can't seem to figure out how to get the first output, though I'm pretty sure I was able to do it in the past.

      Comment


      • #4
        sorry for misreading; try the alpha option

        Comment


        • #5
          Sorry, Rich. That didn't work either; it seems that no matter what I do, everything gets grouped. I can't get the alternating list, which I need to export.

          Comment


          • #6
            Code:
            forval j = 1/59 { 
                 local neworder `neworder' district`j' perhundistrict`j' 
            }
            order `neworder'

            Comment


            • #7
              Thanks, Nick. Since forvalues is for ranges, I don't think that will work. There are some missing values in the sequence. Is there perhaps an alternative method that uses foreach? Something else?

              Comment


              • #8
                You should not expect us to write code that will work if you don't tell us enough about problems in your data that would break it.

                1, 2, 3, ..., X implies integer sequences up to X.

                By missing I guess you mean omitted.

                Code:
                forval j = 1/59 {      
                           capture confirm var district`j'      
                           if _rc == 0 local neworder `neworder' district`j' perhundistrict`j'  
                }
                order `neworder'
                will produce a list skipping omitted values.

                If your data are one step messier, then consider

                Code:
                forval j = 1/59 {      
                      capture confirm var district`j'      
                      if _rc == 0 local neworder `neworder' district`j'      
                      capture confirm var perhundistrict`j'      
                      if _rc == 0 local neworder `neworder' perhundistrict`j'
                }
                order `neworder'
                As you speculate, there could be foreach solutions too.




                Comment


                • #9
                  Code:
                  local neworder
                  unab districtvars : district*
                  foreach var of local districtvars {
                      local neworder `neworder' `var' perhun`var'
                  }
                  order `neworder'
                  (assuming that for each and any variable "district#", there also exists a variable "perhundistrict#"; if not, Nick's solution is less error-prone)
                  Last edited by Daniel Bela; 01 Sep 2016, 08:27.

                  Comment


                  • #10
                    I wouldn't recommend it because it's a bit of a head scratcher but you can do this using rename.

                    Code:
                    * Example generated by -dataex-. To install: ssc install dataex
                    clear
                    input float(id dis16 dis2 dis4 dis9 more4 per16 per2 per4 per9 tail)
                    1 6 2 4 9 4 6 2 4 9 101
                    2 6 2 4 9 4 6 2 4 9 102
                    end
                    
                    rename *# _(##)[2]_*[1]
                    order _*, alpha after(id)
                    rename _(##)_* *[2](#)[1]

                    Comment


                    • #11
                      Another approach, not so elegant but it gets the job done (one variable at a time) and does not rely on having matched pairs.
                      Code:
                      . describe, simple
                      di1  di3  di4  di5  ph1  ph2  ph3  ph4
                      
                      . forval j = 5(-1)1 { 
                        2.      capture order ph`j' 
                        3.      capture order di`j' 
                        4. }
                      
                      . describe, simple
                      di1  ph1  ph2  di3  ph3  di4  ph4  di5
                      
                      .

                      Comment


                      • #12
                        The Olympics inexplicably does not include Stata programming as a sport. I'd like to award medals to Robert and William of unspecified colour for wacky and cute solutions, respectively, or vice versa.

                        Comment


                        • #13
                          Thanks, everyone. William's example code was the one that worked for me. I got what I needed.

                          Comment

                          Working...
                          X