Announcement

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

  • catplot how to sort bars according to percent

    Dear Stata users,

    I use -catplot- (SSC) command to graph bar plot. In the code below, option percent(party) allows me to show percents for each distinct category defined by variable party. So far it's all right, however, I want to sort those bars according to percents that shown by percent(party). And the option var1opts() and var2opts() only allows me to sort bars on percents of party or occupation in the overall (we can get the resultes using tabulate party, sort or tabulate occupation, sort). Is there anyone can guide me to solve this problem? Thank you.

    Code:
    catplot party occupation, var2opts(sort(1) descend) percent(party) blabel(bar, format(%9.1f))
    Code:
    * Example generated by -dataex-. To install: ssc install dataex
    clear
    input float(party occupation)
    1 3
    2 1
    1 1
    2 2
    2 1
    2 2
    1 1
    1 1
    2 1
    1 1
    2 .
    1 1
    1 1
    2 2
    1 2
    1 1
    2 5
    1 1
    2 4
    2 4
    2 4
    2 4
    2 4
    1 1
    2 1
    1 1
    1 1
    2 1
    2 1
    2 1
    2 3
    1 1
    1 1
    1 1
    1 1
    1 1
    1 1
    1 1
    1 1
    2 4
    2 2
    2 1
    2 4
    2 1
    2 4
    2 4
    2 2
    2 1
    1 2
    2 1
    2 1
    2 4
    2 5
    2 5
    2 5
    2 6
    2 5
    2 5
    2 5
    2 5
    2 5
    2 3
    2 3
    2 5
    2 3
    2 5
    2 5
    1 1
    2 1
    1 1
    2 4
    1 1
    1 1
    1 1
    2 4
    2 4
    2 4
    2 4
    2 4
    2 6
    1 3
    1 1
    1 3
    1 1
    1 1
    1 2
    1 1
    1 1
    2 3
    2 3
    1 1
    1 1
    1 1
    1 1
    1 1
    1 .
    1 1
    1 1
    2 3
    1 1
    end
    label values party party
    label def party 1 "democratic", modify
    label def party 2 "republic", modify
    label values occupation occupation
    label def occupation 1 "manager", modify
    label def occupation 2 "worker", modify
    label def occupation 3 "selfemp", modify
    label def occupation 4 "student", modify
    label def occupation 5 "famer", modify
    label def occupation 6 "parttime", modify
    Last edited by Chen Samulsion; 07 Nov 2018, 05:26.

  • #2
    percent(party) gives you the percents of the votes for each party that come from each occupation. That makes sense, but mixes in size of group and voting intention.

    percent(occupation) gives you the percent voting for each parry given their occupation. That is usually is of more interest.

    I don't get what you want, as there are two possible orders for the graph

    Code:
     
     catplot party occupation, percent(party)
    one for the Ds and another for Rs.

    Comment


    • #3
      Nick, thanks as always. Now the plot sorts bars either on percents of party or percents of occupation overall, but I want to sort those bars on percents of party==1, and descending. That is to say, in the imaginary plot, bars of democratic (party==1) are orderd increasing downwards. Sorry for the picture I post below that looks weird with curves and ovals.

      Code:
      . tabulate occupation, sort
      
       occupation |      Freq.     Percent        Cum.
      ------------+-----------------------------------
          manager |         50       51.02       51.02
          student |         16       16.33       67.35
            famer |         12       12.24       79.59
          selfemp |         10       10.20       89.80
           worker |          8        8.16       97.96
         parttime |          2        2.04      100.00
      ------------+-----------------------------------
            Total |         98      100.00
      
      . tabulate party, sort
      
            party |      Freq.     Percent        Cum.
      ------------+-----------------------------------
         republic |         56       56.00       56.00
       democratic |         44       44.00      100.00
      ------------+-----------------------------------
            Total |        100      100.00
      Click image for larger version

Name:	image_12434.png
Views:	1
Size:	48.4 KB
ID:	1469314

      Last edited by Chen Samulsion; 07 Nov 2018, 06:17.

      Comment


      • #4
        I think you just need to create the ordering you want in advance. Here we count D supporters but negate the count to get the sort order you want. If there are ties on that count, we need to split them. For this you need to install labmask from the Stata Journal, to copy over the value labels.

        Code:
        egen Dcount = total(-(party == 1)), by(occupation) 
        egen occupation2 = group(Dcount occupation) 
        labmask occupation2 , values(occupation) decode 
        
        catplot party occupation2 , percent(occupation2)

        Comment


        • #5
          Dear Nick, you emancipate me. I had tried to create the ordering in advance before opening this thread, but failed. The Dcount guides me to get what I want. And yes, the codes you write in #4 is another way (i.e. 'usually is of more interest' as you said in #2) to reveal my data structure. Thank you so much!
          Code:
          egen Dcount = total((party == 1)), by(occupation)
          catplot party occupation, var2opts(sort(Dcount) descend) percent(party) blabel(bar, format(%9.1f))

          Comment


          • #6
            Sorry to add a question. Still using the dataset posted in #1. The codes in #5 do perfect, however if I want more, that not only make Stata sorting on percents of occupations for party==1 (in panel above), but also make it sorting on percents of occupations for party==2 (in panel below). So far I can get what I desire using the following codes: graph separate plots for party==1 (g1) and party==2 (g2), and then combine them (you can see the resulting plot that named "g3"). I doubt that there be another way to get this, particularly with code corresponding to "g0" (i.e. simple one line command without combining). If the answer is no, please let me know, thank you.
            Code:
            egen Dcount = total((party==1)), by(occupation)
            egen Dcount1= total((party==1)), by(occupation)
            egen Dcount2= total((party==2)), by(occupation)
            graph drop _all
            catplot occu party, var1opts(sort(Dcount) descend) percent(party) blabel(bar, format(%9.1f)) nofill name(g0)
            catplot occu party if party==1, var1opts(sort(Dcount1) descending) blabel(bar, format(%9.1f)) percent(party) ylabel("") ytick("") ytitle("") name(g1)
            catplot occu party if party==2, var1opts(sort(Dcount2) descending) blabel(bar, format(%9.1f)) percent(party) ytitle("each party in various ocupations") name(g2)
            graph combine g1 g2, col(1) imargin(zero) xcommon name(g3)

            Comment


            • #7
              This may help. (Shouldn't "famer" be "farmer"?)

              Code:
              bysort party occ: gen count = -_N 
              egen group = group(party count occupation) 
              
              * download from Stata Journal 
              labmask group, values(occupation) decode  
               
              catplot occu party, var1opts(sort(group)) nofill 
              catplot occu, by(party) var1opts(sort(group)) nofill

              Comment


              • #8
                Dear Nick Cox, thank you ever so much. I never thought to use group() function in this situation, Stata is indeed a repository of treasures. Also thanks for -labmask- command. And yes, famer is typo.

                Comment

                Working...
                X