29

Given the following dataset:

   Division Year OperatingIncome
1  A  2012           11460
2  B  2012            7431
3  C  2012           -8121
4  D  2012           15719
5  E  2012             364
6  A  2011           12211
7  B  2011            6290
8  C  2011           -2657
9  D  2011           14657
10 E  2011            1257
11 A  2010           12895
12 B  2010            5381
13 C  2010           -2408
14 D  2010           11849
15 E  2010             517

How do I complete a stacked bar chart in ggplot2 that includes the negative values? Here's the basic chart sequence I'm using:

ggplot(income_m, aes(x=Year, y=OperatingIncome, fill=Division)) + geom_bar() +
+ scale_fill_brewer(type = "seq", palette = 1)

This returns an error:

Warning message: Stacking not well defined when ymin != 0

And instead of the expected result - negative values being displayed below the X axis - they are simply not present in the stacked bar chart. Is there a way to produce the chart with all values, both positive and negative, accounted for?

smci
  • 32,567
  • 20
  • 113
  • 146
sogrady
  • 756
  • 3
  • 8
  • 12
  • Are you looking for something like this http://stackoverflow.com/questions/12312189/r-floating-barchart/12312457#12312457 – mnel Dec 05 '12 at 23:28
  • more like this: http://www.infragistics.com/uploadedImages/Content/Products/ASPNET/Whats_new/PositiveNegativeStackChartWeb.png – sogrady Dec 05 '12 at 23:34

1 Answers1

51

Update: As of ggplot2 2.2.0, stacking for negative values is handled automatically, without having to create separate layers for the positive and negative values.

If I understand what you're looking for, the trick is to put the two positive and negative data in separate layers, and also to use stat = "identity":

dat <- read.table(text = "   Division Year OperatingIncome
1  A  2012           11460
2  B  2012            7431
3  C  2012           -8121
4  D  2012           15719
5  E  2012             364
6  A  2011           12211
7  B  2011            6290
8  C  2011           -2657
9  D  2011           14657
10 E  2011            1257
11 A  2010           12895
12 B  2010            5381
13 C  2010           -2408
14 D  2010           11849
15 E  2010             517",header = TRUE,sep = "",row.names = 1)

dat1 <- subset(dat,OperatingIncome >= 0)
dat2 <- subset(dat,OperatingIncome < 0)
ggplot() + 
    geom_bar(data = dat1, aes(x=Year, y=OperatingIncome, fill=Division),stat = "identity") +
    geom_bar(data = dat2, aes(x=Year, y=OperatingIncome, fill=Division),stat = "identity") +
    scale_fill_brewer(type = "seq", palette = 1)

enter image description here

joran
  • 169,992
  • 32
  • 429
  • 468
  • 2
    I want something along these lines - but i want my stack to be a sum of values - thus if there is negative values in A in 2010 i would like to subtract them from the total sum of A in 2010 - how would that work? – Lmm Apr 26 '19 at 21:07