1
votes

I have following code to graph a contracts in different countries.

Country <- CCOM$Principal.Place.of.Performance.Country.Name
Val <- CCOM$Action_Absolute_Value
split <- CCOM$Contract.Category

ggplot(CCOM, aes(x = Country, y = Val, fill = levels(split))) +
    geom_bar(stat = "identity")

I want a simple stacked bar chart with the bars colored by the contract category which is the variable "split" (ie. CCOM$Contract.Category).

However when I run the code it produces the graph below:

enter image description here

Why won't gplot separate the spending into three distinct blocks? Why do I get color sections scattered throughout the chart.? I have tried using factor(split) and levels(split) but does not seem to work. Maybe I am putting it in the wrong position.

2
Try ggplot(CCOM, aes(x = Country, y = Val, fill = Contract.Category))Andrie
Please add a minimal sample of your data, so the code will be reproducible.tonytonov
It's ok. when I order the dataset by the contract category, it works. I don't know why I have to do that though. Shouldn't need to, but in the short term the problem is solved.user2907249
You need to do it because of the weird thing you're doing defining an extra variable split <- CCOM$Contract.Category and then using levels(split) as the fill. If don't do those extra weird steps and use fill = Contract.Category as Andie suggests, you should be fine.Gregor Thomas
In the same line as @Andrie's comment, a better call should use the data frame names instead: ggplot(CCOM, aes(x = Principal.Place.of.Performance.Country.Name, y = Action_Absolute_Value, fill = Contract.Category)). Terribly long names, that make for a hard-to-read code, though...PavoDive

2 Answers

1
votes

Ah, I just realized what was going on. You seem scared to modify your data frame, don't be! Creating external vectors for ggplot is asking for trouble. Rather than create Country and Val as loose vectors, add them as columns to your data:

CCOM$Country <- CCOM$Principal.Place.of.Performance.Country.Name
CCOM$Val <- CCOM$Action_Absolute_Value

Then your plot is nice and straightforward, you don't have to worry about order or anything else.

ggplot(CCOM, aes(x = Country, y = Val, fill = Contract.Category)) +
    geom_bar(stat = "identity")
0
votes

as you suggest order provides a solution:

ggplot(CCOM[order(CCOM$split), ], aes(x = Country, y = Val, fill = Contract.Category)) +
   geom_bar(stat = "identity")

I have a similar example where I use the equivalent of fill as Contact.Category and it still requires the reordering.