3

I have a dataframe with programs and a country for each person in the program. I need to make a bar plot for each program with counts of participants from each country. I am including sample data and the code below.

In reality I have over 20 programs with hundreds of entries for each country and would like to automate this process to iterate over all of the programs by only changing the name of the program in the code. In the bar plot, I need to have data labels on the outer ends of the horizontal bars, however this prints them beyond the limits of the plot window. To solve this, I would like to adjust the scale of the axis, however instead of adjusting it manually for each program, I would like to set the limit to 10% above the maximum value of the 'Count' variable.

My question is whether it is possible to use variable values from a dataframe to set the limits instead of hardcoding them for each plot (and preferably doing this without saving a separate table for country counts). If this is not something that can be done, does anyone know of efficient alternative methods to automate axes scale adjustments and/or adjusting the plot window to fit the labels?

I could not find an answer to this elsewhere, but if a similar question has already been answered, I would be grateful if someone can point me towards the solution.

sample_data <- data.frame(
                          "person_number" = 1:15, 
                          "country" = c("United States", "Canada", "India", "United States", "United 
                                         States", "United States", "India", "China", "China", "United 
                                         States", "China", "India", "Canada", "United States", "China"), 
                          "program" = c("Program1", "Program2", "Program3", "Program2", "Program3", 
                                        "Program3", "Program3", "Program2", "Program3", "Program1", 
                                        "Program1", "Program3", "Program1", "Program2", "Program1")
                          )
sample_data %>% 
    filter(program == "Program1") %>% 
    group_by(country) %>% 
    summarise(Count = n_distinct(person_number)) %>% 
    ggplot(aes(x = reorder(country, Count), y = Count)) +
      geom_bar(stat = "identity", fill = "salmon3") +
      coord_flip() +
      labs(title = "Country for Program1 Applicants") +
      geom_text(aes(label=Count), size=3, hjust=-0.2) +
      ylim(0, max(Count)+0.1*max(Count))                     # this line does not work
                                                             # error message: object 'Count' not found
3
  • 2
    try putting your y-axis limits in coord_flip(ylim = c(0, max(Count)+0.1*max(Count))) Commented Jan 9, 2020 at 16:08
  • @M_Shimal I get an error message saying "object 'Count' not found" Commented Jan 9, 2020 at 16:15
  • Yea, my solution in the comment is actually wrong. It doesn't recognise count. You should perhaps do max() out of ggplot and include it there as a vector. Commented Jan 9, 2020 at 16:35

1 Answer 1

7

This is exactly what the expand parameter in a scale is meant for. We can set a multiplicative axis expansion.

We can also simplify your code a bit:

sample_data %>% 
  filter(program == "Program1") %>% 
  ggplot(aes(x = forcats::fct_infreq(country))) +
  geom_bar(fill = "salmon3") +
  geom_text(aes(label = stat(count)), stat = 'count', size = 3, hjust = -0.2) +
  labs(title = "Country for Program1 Applicants") +
  scale_y_continuous(expand = expansion(c(0, 0.1))) +
  coord_flip()

I also turned off expansion of the left side of the plot. See ?scale_y_continuous and ?expansion.

enter image description here

Sign up to request clarification or add additional context in comments.

1 Comment

Really useful answer. expand_scale() is deprecated; use expansion() instead.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.