1

I am trying to make a stacked bar plot which shows what percent of each team's hits are singles, doubles, triples, and home runs. However, as you can see from the attached picture, I keep getting a weird result. I think I went wrong on the melt step because I am not sure how to use that function. The graph, if done correctly, should have four stacked bars on each row with the total length of all four bars equaling one on each row. Note you have to scroll to view more code.

Any help fixing this issue would be greatly appreciated.

df <- read.table(textConnection(
'Team   Doubles Triples     HR          Singles
ARI 0.192697769 0.037863421 0.128465179 0.640973631
ATL 0.21011396  0.019230769 0.086894587 0.683760684
BAL 0.187544232 0.004246285 0.179051663 0.62915782
BOS 0.214643304 0.015644556 0.130162703 0.639549437
CHC 0.2079489   0.021291696 0.141234918 0.629524485
CHW 0.193977591 0.023109244 0.117647059 0.665266106
CIN 0.19743407  0.023521026 0.116892373 0.66215253
CLE 0.214634146 0.020209059 0.128919861 0.636236934
COL 0.205958549 0.030440415 0.132124352 0.631476684
DET 0.170731707 0.020325203 0.14295393  0.66598916
HOU 0.212874909 0.021214338 0.144842721 0.621068032
KCR 0.182068966 0.022758621 0.10137931  0.693793103
LAA 0.19787234  0.014184397 0.110638298 0.677304965
LAD 0.197674419 0.015261628 0.137354651 0.649709302
MIA 0.17739726  0.028767123 0.087671233 0.706164384
MIL 0.191685912 0.014626636 0.149345651 0.644341801
MIN 0.204400284 0.024840312 0.141944642 0.628814762
NYM 0.178837556 0.014157973 0.162444113 0.644560358
NYY 0.177793904 0.014513788 0.132801161 0.674891147
OAK 0.199704142 0.015532544 0.125       0.659763314
PHI 0.177011494 0.026819923 0.123371648 0.672796935
PIT 0.194249649 0.022440393 0.107293128 0.67601683
SDP 0.201568627 0.020392157 0.138823529 0.639215686
SEA 0.173582296 0.01175657  0.154218534 0.6604426
SFG 0.194850383 0.037578288 0.090466249 0.67710508
STL 0.21130742  0.022614841 0.159010601 0.607067138
TBR 0.216054014 0.024006002 0.16204051  0.597899475
TEX 0.177731674 0.015905947 0.14868603  0.657676349
TOR 0.203240059 0.013254786 0.162739323 0.620765832
WSN 0.191019244 0.020669993 0.14468995  0.643620813'), header = TRUE)

library(ggplot2)
library(reshape2)

hw <- theme_gray() + theme(
  strip.background=element_rect(fill=rgb(.9,.95,1),
    colour=gray(.5), size=.2),

  panel.border=element_rect(fill=FALSE,colour=gray(.70)),
  panel.grid.minor.y = element_blank(),
  panel.grid.major.y = element_blank(),
  panel.spacing.x = unit(0.10,"cm"),
  panel.spacing.y = unit(0.05,"cm"),

  axis.ticks=element_blank(), 
  axis.text=element_text(colour="black"),

  axis.text.y=element_text(margin=margin(0,0,0,3)),
  axis.text.x=element_text(margin=margin(-1,0,3,0))
)



ord <- with(df,order(Singles,Doubles,Triples,HR))
dfOrd <- df[ord,]


tmp <- as.character(dfOrd$Team)
dfOrd$Team <- factor(tmp,rev(tmp))



tmp <- as.character(dfOrd$Team)
dfOrd$Team <- factor(tmp,rev(tmp)) 



colnames(dfOrd)


dfLong <- melt(dfOrd[,-c(0,4)],
  value.name="Percent", 
  variable.name="Achievement")
head(dfLong)
tail(dfLong)



ggplot(dfLong,aes(x=Team,y=Percent,fill=Achievement)) + 
geom_bar(stat="identity",alpha=I(1),color=gray(.2),width=.75,size=.4)+
 coord_flip() + hw + 
 theme(legend.position="top",
 axis.text.y=element_text(size = rel(.8)))+
 labs(fill="", y="Percent",
 title="Title")

Image

Konrad Rudolph
  • 530,221
  • 131
  • 937
  • 1,214
Remy M
  • 599
  • 1
  • 4
  • 17
  • 2
    If you want to plot info from all 4 columns, why do you remove the `HR` column prior to melting? You remove the fourth column in `dfOrd[,-c(0,4)]`. Try `melt(dfOrd)` instead. – aosmith Apr 05 '17 at 16:22
  • Oh, I didn't mean to do that. I was using a program as a guideline and wasn't sure what that function was doing. I'll try that now. – Remy M Apr 05 '17 at 16:23
  • Ok, I did that and it looks good for the most part. How could I make the order of the bars be singles, doubles, triples, homers and make the legend be in that same order? Do I have to edit the data frame or is there a quick fix? – Remy M Apr 05 '17 at 16:28
  • Change the order of the levels of the factor. Lots of questions/answers on SO about this. – aosmith Apr 05 '17 at 16:30

1 Answers1

2
library(ggplot2)
library(reshape2)
library(dplyr)
library(scales)

df %>% melt(id.var="Team") %>%
  mutate(variable = factor(variable, levels=rev(c("Singles","Doubles","Triples","HR"))),
         Team = factor(Team, levels=df$Team[order(df$Singles)])) %>%
  ggplot(aes(Team, value, fill=variable)) +
  geom_bar(stat="identity") +
  coord_flip() +
  scale_y_continuous(labels=percent) +
  theme_classic() +
  theme(legend.position="bottom",
        axis.title.x=element_blank()) +
  guides(fill=guide_legend(reverse=TRUE)) +
  labs(fill="", y="")

enter image description here

eipi10
  • 91,525
  • 24
  • 209
  • 285
  • I implemented fill=factor(variable, levels=(c("Singles","Doubles","Triples","HR"))) into my program and it changed the legend to what you have but I am having difficulty having the bars share that same order. When I do rev(c( it changes the order of both. – Remy M Apr 05 '17 at 16:45