1

(I am newbie in R).

I have created a outer function with 3 inner functions that preprocess data & plot.

Issues I am facing is in using country name dynamically - in passing them on y axis and also use them inside labs for titles/subtitles.

Adding snapshot below of problem areas (This is working when I am using static country name)

enter image description here

But when I use country names argument i.e bench_country like {bench_country} or !!bench_country or !!enquo(bench_country) then it doesn't work.

Adding snapshot below of problem areas (This is not working with argument bench_country = India)

enter image description here

I have used {} for other arguments that works but {bench_country} has been causing issues at most places

Adding Code below to replicate issue:

library(tidyverse)
library(glue)
library(scales)

gapminder <- read.csv("https://raw.githubusercontent.com/swcarpentry/r-novice-gapminder/gh-pages/_episodes_rmd/data/gapminder-FiveYearData.csv")

gapminder <- gapminder %>% mutate_if(is.character, as.factor)

################ fn_benchmark_country ################


fn_benchmark_country_last  <- 
  function(bench_country = India){
  
      bench_country = enquo(bench_country) # <======================================= enquo used
    
      gapminder_benchmarked_wider <- gapminder %>% 
                                      select(country, year, gdpPercap) %>% 
                                      pivot_wider(names_from = country, values_from = gdpPercap) %>% 
                                      arrange(year) %>% 
                                      # map_dbl( ~{.x - India })
                                      mutate(across(-1, ~ . - !!bench_country))
                                      
      # Reshaping back to Longer
      gapminder_benchmarked_longer <- gapminder_benchmarked_wider %>% 
                                      pivot_longer(cols = !year, names_to = "country", values_to = "benchmarked") 
     
      # Joining tables
      gapminder_joined <- left_join(x = gapminder, y = gapminder_benchmarked_longer, by = c("year","country"))
    
      # converting to factor
      gapminder_joined$country <- as.factor(gapminder_joined$country)
      
      # gapminder_joined <<- gapminder_joined 
      # (this pushes it to Global evrn)
      
      return(gapminder_joined)
  
}  

################ ----------------------------- ################



################ fn_year_filter ################

# filtering years 

fn_year_filter_last  <- 
  function(gapminder_joined, year_start, year_end){

      gapminder_joined %>% 
      filter(year %in% c(year_start,year_end)) %>% 
      
      arrange(country, year) %>% 
      
      group_by(country) %>% 
      
      mutate(benchmark_diff = benchmarked[2] - benchmarked[1],
             max_pop = max(pop)) %>% 
      
      ungroup() %>% 
      
      arrange(benchmark_diff) %>% 
      
      filter(max_pop > 30000000) %>% 
      
      mutate(country = droplevels(country)) %>% 
      select(country, year, continent, benchmarked, benchmark_diff) %>% 
        
      # --- 
      mutate(country = fct_inorder(country)) %>% 
      
      group_by(country) %>% 
        
      mutate(benchmarked_end = benchmarked[2],
             benchmarked_start = benchmarked[1]  ) %>% 
      
      ungroup() 

  }

################ ----------------------------- ################



################ fn_create_plot ################
  
fn_create_plot_last <- 
  function(df, year_start, year_end, bench_country ){
    
    # plotting
        ggplot(df) + 
        
        geom_segment(aes(x = benchmarked_start, xend = benchmarked_end,
                         y = country, yend = country,
                         col = continent), alpha = 0.5, size = 7) +
        
        geom_point(aes(x = benchmarked, y = country, col = continent), size = 9, alpha = .8) +
        
        geom_text(aes(x = benchmarked_start + 8, y = country,
                      label = paste(round(benchmarked_start))),
                  col = "grey50", hjust = "right") +
        
        geom_text(aes(x = benchmarked_end - 4.0, y = country,
                      label = round(benchmarked_end)),
                  col = "grey50", hjust = "left") +
      
        # scale_x_continuous(limits = c(20,85)) +
        
        scale_color_brewer(palette = "Pastel2") +
        
        labs(title = glue("Countries GdpPerCap at {year_start} & {year_end})"),
             subtitle = "Meaning Difference of gdpPerCap of countries taken wrt India \n(Benchmarked India in blue line) \nFor Countries with pop > 30000000 \n(Chart created by ViSa)",
             col = "Continent", 
             x = glue("GdpPerCap Difference at {year_start} & {year_end} (w.r.t India)") ) +

       
    # Adding benchmark line      
        geom_vline(xintercept = 0, col = "blue", alpha = 0.3) +
      
        geom_label( label="India- as Benchamrked line", x=8000, y= !!bench_country, # {bench_country} 
          label.padding = unit(0.35, "lines"), # Rectangle size around label
          label.size = 0.15, color = "black") +  
      
        # background & theme settings
        theme_classic() +
    
    theme(legend.position = "top", 
          axis.line = element_blank(), # axis.text = element_blank() 
          axis.ticks = element_blank()
          ) +
         
    # Adding $ to the axis (from scales lib)            <=========================
        scale_x_continuous(labels = label_dollar()) 
    
}

################ ----------------------------- ################



################  Calling functions  ################

fn_run_all_last <-function(bench_country = India, year_start = 1952, year_end = 2007){
  
  
  year_start = year_start
  year_end = year_end
  
  # Function1 for PreProcess Benchmarked Country
     gapminder_joined <- fn_benchmark_country_last({{bench_country}}) 

  # Function2 to PreProcess dates & pass df to function3 to plot  
      Plot_last <- fn_year_filter_last(gapminder_joined, year_start, year_end) %>% 
      
                      fn_create_plot_last(., year_start, year_end, {{bench_country}})

  
  # Pusing plot object to global
       Plot_last <<- Plot_last
  
  # Printing Plot
      Plot_last
  }

fn_run_all_last(India, 1952, 2007)

1 Answer 1

2

To make your code work use rlang::as_label(enquo(bench_country)) in geom_label instead of !!bench_country or the other options you have tried. While enquo quotes the argument rlang::as_label converts the argument or the expression to a string which can then be used as label.

With this change I get:

enter image description here

EDIT For reference here is the full code for the plotting function. I also adjusted the code to take make the title and axis label "dynamic". To avoid duplicating code I add new variable at the beginning of the function which I assign the country label as a character:

fn_create_plot_last <-
  function(df, year_start, year_end, bench_country) {

    bench_country_str <- rlang::as_label(enquo(bench_country))
    
    # plotting
    ggplot(df) +
      geom_segment(aes(
        x = benchmarked_start, xend = benchmarked_end,
        y = country, yend = country,
        col = continent
      ), alpha = 0.5, size = 7) +
      geom_point(aes(x = benchmarked, y = country, col = continent), size = 9, alpha = .8) +
      geom_text(aes(
        x = benchmarked_start + 8, y = country,
        label = paste(round(benchmarked_start))
      ),
      col = "grey50", hjust = "right"
      ) +
      geom_text(aes(
        x = benchmarked_end - 4.0, y = country,
        label = round(benchmarked_end)
      ),
      col = "grey50", hjust = "left"
      ) +

      # scale_x_continuous(limits = c(20,85)) +

      scale_color_brewer(palette = "Pastel2") +
      labs(
        title = glue("Countries GdpPerCap at {year_start} & {year_end})"),
        subtitle = glue("Meaning Difference of gdpPerCap of countries taken wrt {bench_country_str} \n(Benchmarked {bench_country_str} in blue line) \nFor Countries with pop > 30000000 \n(Chart created by ViSa)"),
        col = "Continent",
        x = glue("GdpPerCap Difference at {year_start} & {year_end} (w.r.t {bench_country_str})")
      ) +


      # Adding benchmark line
      geom_vline(xintercept = 0, col = "blue", alpha = 0.3) +
      geom_label(
        label = glue("{bench_country_str} - as Benchamrked line"), x = 8000, y = bench_country_str, # {bench_country}
        label.padding = unit(0.35, "lines"), # Rectangle size around label
        label.size = 0.15, color = "black"
      ) +

      # background & theme settings
      theme_classic() +
      theme(
        legend.position = "top",
        axis.line = element_blank(), # axis.text = element_blank()
        axis.ticks = element_blank()
      ) +

      # Adding $ to the axis (from scales lib)            <=========================
      scale_x_continuous(labels = label_dollar())
  } 
Sign up to request clarification or add additional context in comments.

6 Comments

Thanks @stefan that worked in geom_label but I am still not able to solve this in labs for title, subtitles ..I have tried {!!bench_country} and many other combinations as well but nothing helped
Hi @ViSa. I just made an edit and included the full code for your plotting function. I checked by using "Germany" as benchmark that all annotations now get the right label.
Thanks alot @stefan for the help !!
@ViSa FYI a single { only does something inside glue strings. In normal code it's equivalent to a ( parenthesis. These { in the code may be a bit confusing because they make it seem you're trying to interpolate data-arguments with {{.
Thanks @LionelHenry for explaining about {. I am highly confused with {, quos, enquous, rlang smb, as_label and many other such things and looking for good links to learn as without learning these I get stuck in every function that I create.
|

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.