Announcement

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

  • How to rearrange bars in bar graph with two variables and two over groups

    Hi all,

    I feel like I should know how to do this - but I'm trying to plot two variables with two sets of over groups. The way the graphs come out, the bars of the two variables are next to each other, within the over groups. But what I would like is for all the bars of each variable to be next to each other within the first over group. In case this sounds vague, I've included code and the resulting graph below.

    HTML Code:
    clear all
    set obs 12
    set seed 123456
    
    gen year = . replace year = 2009 in 1/4
    replace year = 2013 in 5/8
    replace year = 2017 in 9/12
    
    gen color = ""
    replace color = "Red" if inlist(_n, 1, 5, 9)
    replace color = "Blue" if inlist(_n, 2, 6, 10)
    replace color = "Orange" if inlist(_n, 3, 7, 11)
    replace color = "Green" if inlist(_n, 4, 8, 12)
    
    gen percent_favorite = .
    replace percent_favorite = rnormal(.29, .05) if color=="Red"
    replace percent_favorite = rnormal(.41, .05) if color=="Blue"
    replace percent_favorite = rnormal(.13, .05) if color=="Orange"
    egen total = total(percent_favorite), by(year)
    replace percent_favorite = 1 - total if color=="Green"
    drop total
    
    gen percent_least_favorite = .
    replace percent_least_favorite = rnormal(.15, .05) if color=="Red"
    replace percent_least_favorite = rnormal(.11, .05) if color=="Blue"
    replace percent_least_favorite = rnormal(.42, .05) if color=="Orange"
    egen total = total(percent_least_favorite), by(year)
    replace percent_least_favorite = 1 - total if color=="Green"
    drop total
    
    graph bar percent_favorite percent_least_favorite, over(year) over(color) scheme(538) legend(pos(6) rows(1)) 
    The resulting graph looks like this:

    Click image for larger version

Name:	fake_data_graph.png
Views:	1
Size:	31.8 KB
ID:	1568505


    Basically - I would like all of the mean of percent_favorite bars for each year to be next to each other within the Blue group and then the mean of percent_least_favorite within the blue group next to each other. I tried asyvars, but it doesn't work. So I'm stumped. Any help would be greatly appreciated.


  • #2
    Thanks for the data example, although the code won't run as intended unless the community-contributed scheme 538 is installed and anyone trying to run this should note that


    Code:
     
     gen year = . replace year = 2009 in 1/4
    should be two lines, not one line. I found your names Blue Green Orange Red to be disconcerting when there are red and blue bars that don't relate to that set. These are trivia. I also note that my random numbers are not the same as yours even with the same seed, so I wonder if you are using some version of Stata before 16.1, which doesn't bite here, but FAQ Advice is to tell us about that.

    Everyone thinks that bar charts should be trivial, but if you were to say to a research assistant "all I want is a simple bar chart with two outcome variables and two classifying variables" there would still be a question of what precisely you want.

    I have a solution to offer, which in no sense rules out a simpler solution. My slogan is always "Lose the legend! Kill the key!" (if you can).

    Code:
    clear all
    set obs 12
    set seed 123456
    
    gen year = . 
    replace year = 2009 in 1/4
    replace year = 2013 in 5/8
    replace year = 2017 in 9/12
    
    gen color = ""
    replace color = "A" if inlist(_n, 1, 5, 9)
    replace color = "B" if inlist(_n, 2, 6, 10)
    replace color = "C" if inlist(_n, 3, 7, 11)
    replace color = "D" if inlist(_n, 4, 8, 12)
    
    gen percent_favorite = .
    replace percent_favorite = rnormal(.29, .05) if color=="A"
    replace percent_favorite = rnormal(.41, .05) if color=="B"
    replace percent_favorite = rnormal(.13, .05) if color=="C"
    egen total = total(percent_favorite), by(year)
    replace percent_favorite = 1 - total if color=="D"
    drop total
    
    gen percent_least_favorite = .
    replace percent_least_favorite = rnormal(.15, .05) if color=="A"
    replace percent_least_favorite = rnormal(.11, .05) if color=="B"
    replace percent_least_favorite = rnormal(.42, .05) if color=="C"
    egen total = total(percent_least_favorite), by(year)
    replace percent_least_favorite = 1 - total if color=="D"
    drop total
    
    * new code starts here 
    stack percent_favorite color year percent_least_favorite color year , into(percent color year) clear 
    label def _stack 1 favorite 2 least 
    label val _stack _stack 
    separate percent, by(_stack) veryshortlabel
    set scheme s1color 
    
    graph bar (asis) percent?, over(year, relabel(1 "09" 2 "13" 3 "17")) over(_stack) ///
    by(color, note("") row(1) legend(off)) bar(1, color(blue*0.5)) bar(2, color(red*0.5)) subtitle(, fcolor(none))
    Click image for larger version

Name:	libassi.png
Views:	1
Size:	25.0 KB
ID:	1568544


    Comment


    • #3
      This is great - thanks so much, Nick. I will try to do a better job of keeping my code clean next time I post and keeping track of what version I'm using. Really appreciate the reply.

      Comment

      Working...
      X