I would like to label each of the boxes in a barplot by their size(i.e number of observations in dataframe which are in the group).
e.g If the first variable has 3 levels and the second variable has 4 levels, I would like 12 labels.
(Also, is it possible to control the size or position of these labels)
Thank you for any help.
Here’s one way to do it, using the data
VADeathsas an example (it will be in your R workspace by default, or if not, uselibrary(datasets)).It looks like this:
To modify the size of the font you can use
text(...,cex=2)to make things twice the size they were, e.g.Now, let’s explain this code so you know how to do it yourself!
First, let’s look at
VADeaths: it’s a tally of deaths in each age group by category:Now, to do the text on the barplot, we basically draw the barplot, and then draw the text on top using R command
text(see?text).textrequires x,y coordinates and corresponding pieces of text to draw on the bar plot. We will give it the coordinates of each line in the bar plot to draw the text on.To do this, see the “Value” section
?barplot. This function not only plots your bar plot, but returns the x coordinate of each bar. score!Now all we need is y coordinates to go with our x coordinates.
Well, a stacked bar plot just tallies up the frequencies in
VADeathsas you go along.For example, in the ‘Rural Male’ group, the first line is drawn at
11.7, and the second is drawn at11.7 + 18.1 = 29.8, the third at11.7 + 18.1 + 26.9 = 56.7, and so on (see the values inVADeaths).So, our y coordinates need to be cumulative sums going down the columns.
To calculate these for each column, we can use
cumsum. For exampleSince we want to do this for each column in
VADeaths, we have to use the functionapply.apply(VADeaths,2,cumsum)means: “For each column inVADeaths, calculate thecumsumof that”.This gives us the y values for each line of the bar plot.
Let’s save these yvalues for further use:
The reason I use
as.vectoris just to flatten the matrix into a vector of values — it makes the plotting easier.One last thing — my x values (that I stored in
bar) only have one value per bar, but I need to expand it out so there’s one x value per line on each bar. To do this:This turns my previous
x1,x2,x3,x4intox1,x1,x1,x1,x1, x2,x2,x2,x2,x2, ..., x4,x4,x4,x4,x4.Now my
xvalsmatch myyvals.After this it’s simply a case of using
text.The
labelsarguments tellstextwhat text to put at the x/y positions.The
pos=3means “draw each bit of text just above my specified x/y value”. Otherwise, the numbers would be drawn over the lines of the barplot which would be hard to read.Now, there are many options for customising the position and size of text, and I suggest you read
?textto see them.All this code condenses down to the two-liner I gave at the beginning of the answer, but this version might be a little more understandable: