Search code examples
rplotbar-chart

Making a barchart where each column of the dataframe becomes a separate bar


I am looking to find a way to make a data frame that has each column a different group, to be a bar. The values below is are the data points for that respective group.

Goal: to make a bar chart with mean standard error with the marker plots on... I tried to put mean standard error bars on them, with each data point being labeled on the bar chart as well, but currently, I am facing with the issue of being able to plot the bars.

I looked on other stackoverflows, and other ggplot2 resources online for this. I'm not sure why I am blanking out on this...

In the column category, there are three groups that I would like to make a bar plot for. The ratio column has the data points.

category <- c("c1", "d1", "ff", "ff", "d1", "d1", "c1", "c1")
ratio <- c(3,2,5,6,1,1.5, 4, 4.5)

df <- data.frame(category, ratio)

I would appreciate any advice on this please! Thank you


Solution

  • These can be tricky. geom_bar() by default just counts things in a single variable, and geom_col() by default draws bars for each y value you supply it, and also stacks them on top of each other with its position = "stack" default argument.

    This basic method below has served me well and allows you to keep the data in long format with the measurements for each replicate.

    Instead of geom_col(), we use stat_summary() to take the means of the y aesthetic and then we specify geom = "col". We do similarly for the errorbars. In these stat_ functions, we can use fun for a single y aesthestic (as needed for geom_col) or we can use fun.data to return ymin, y, and ymax, as called for by geom_errorbar(). ggplot2::mean_se() is a function meant specifically for stat_summary() which returns these three values.

    library(ggplot2)
    
    ggplot(df, aes(x = category, y = ratio)) +
        stat_summary(
            geom = "col",
            fun = mean
        ) +
        stat_summary(
            geom = "errorbar",
            fun.data = mean_se,
        ) +
        geom_point()
    

    This is somewhat ugly by default. We can spice it up by adding a fill aesthetic to the bars, jitter to the points, and other visual details.

    ggplot(df, aes(x = category, y = ratio)) +
        stat_summary(
            aes(fill = category),
            geom = "col",
            fun = mean,
            width = 0.85,
            color = "black"
        ) +
        stat_summary(
            geom = "errorbar",
            fun.data = mean_se,
            width = 0.5,
            linewidth = 0.5
        ) +
        geom_point(
            shape = 21,
            size = 2,
            fill = "white",
            position = position_jitter(width = 0.2)
        ) +
        theme(legend.position = "none")