Peanut - 1 year ago 111

R Question

I found a plot in a stats book, which I want to reproduce with the base package.

The plot looks like this:

So far I have the plot, but I have problems to add a centred labels to each part of the bar.

My code looks like this:

`data <- sample( 5, 10 , replace = TRUE )`

colors <- c('yellow','violet','green','pink','red')

relative.frequencies <- as.matrix( prop.table( table( data ) ) )

bc <- barplot( relative.frequencies, horiz = TRUE, axes = FALSE, col = colors )

Answer Source

For your given example, we can do:

```
set.seed(0) ## `set.seed` for reproducibility
dat <- sample( 5, 10 , replace = TRUE )
colors <- c('yellow','violet','green','pink','red')
h <- as.matrix( prop.table( table( dat ) ) )
bc <- barplot(h, horiz = TRUE, axes = FALSE, col = colors )
## compute x-location of the centre of each bar
H <- apply(rbind(0, h[-nrow(h), ]), 2L, cumsum) + h / 2
## add text
text(H, bc, labels = paste0(100 * h, "%"))
```

In the above, computation of `H`

is the key. It is related to how `barplot`

determines the height of the bar to plot when producing stacked bar-chart.

We first consider the vector case. If you have a vector of height, say `h`

, then the height of stacked bar-chart is `cumsum(h)`

. So the centre of each stacked bar is

```
cumsum(c(0, h))[-length(h)] + h
```

Now if we have a matrix input `h`

, we simply want to use `apply`

to apply the above to all columns (Margin: 2) of `h`

, hence we want:

```
apply(rbind(0, h)[-nrow(h)], 2L, cumsum) + h / 2
```

Finally we use `text`

for add text to the plot.