rtidyevalr-glue

Using character object to indicate column name within R's glue function?


I am trying to create a "label" column in my dataset using the glue::glue function. I want each row of this label column to include the value of a user-selected column. For example, using the mtcars dataset, I'd like to create a label column that glues the vehicle name and the value of another column of my choice. Doing so for a single explicitly defined column is fine; I just put the name of the column in the glue function directly (see my example with mpg below).

library(glue)
library(tidyverse)

data <- mtcars %>% as_tibble(rownames = "Vehicle")

#This is easy to do if I know in advance I want to use mpg. I just put it in the glue function directly
data %>% 
  mutate(Label=glue("{Vehicle}: {value}",
                    value=mpg)) %>% 
  select(Label)
#> # A tibble: 32 x 1
#>    Label                  
#>    <glue>                 
#>  1 Mazda RX4: 21          
#>  2 Mazda RX4 Wag: 21      
#>  3 Datsun 710: 22.8       
#>  4 Hornet 4 Drive: 21.4   
#>  5 Hornet Sportabout: 18.7
#>  6 Valiant: 18.1          
#>  7 Duster 360: 14.3       
#>  8 Merc 240D: 24.4        
#>  9 Merc 230: 22.8         
#> 10 Merc 280: 19.2         
#> # ... with 22 more rows

Created on 2021-02-28 by the reprex package (v1.0.0)

The issue is that I want to generalize. I'd like to define which column to glue outside of the glue function itself. Ultimately I'd like to set this column of interest as a parameter in a function.

To illustrate my roadblock, I've created a character object, outside of the glue function, equal to the column I want to use. For example, I define column_of_interest as "mpg". The behavior I want is for glue to recognize that when I say column_of_interest, which is equal to "mpg", I mean to look at the mpg column, not to glue the word "mpg" itself. Perhaps unsurprisingly, glue does the latter:

library(glue)
library(tidyverse)
data <- mtcars %>% as_tibble(rownames = "Vehicle")

#I would like to set the column to glue here
column_of_interest <- "mpg"
#And then use the column_of_interest object here
data %>% 
  mutate(Label=glue("{Vehicle}: {value}",
                    value=column_of_interest)) %>% 
  select(Label)
#> # A tibble: 32 x 1
#>    Label                 
#>    <glue>                
#>  1 Mazda RX4: mpg        
#>  2 Mazda RX4 Wag: mpg    
#>  3 Datsun 710: mpg       
#>  4 Hornet 4 Drive: mpg   
#>  5 Hornet Sportabout: mpg
#>  6 Valiant: mpg          
#>  7 Duster 360: mpg       
#>  8 Merc 240D: mpg        
#>  9 Merc 230: mpg         
#> 10 Merc 280: mpg         
#> # ... with 22 more rows

Created on 2021-02-28 by the reprex package (v1.0.0)

I am wondering if it is possible to do the former? Is possible to get glue to recognize that by column_of_interest="mpg" I mean I want the value of the mpg column, not the literal word "mpg"?

I am vaguely familiar with tidy evaluation (very vaguely), and have tried a few tricks there (mostly putting !! in front of column_of_interest). None were successful. Any help would be greatly appreciated, and happy to provide more information if that'd be helpful.


Solution

  • There are multiple ways you can do this :

    1. With .data :
    library(dplyr)
    library(glue)
    data <- mtcars %>% as_tibble(rownames = "Vehicle")
    
    column_of_interest <- "mpg"
    
    data %>% 
      mutate(Label=glue("{Vehicle}: {value}",value=.data[[column_of_interest]])) %>% 
      select(Label)
    
    #   Label                  
    #   <glue>                 
    # 1 Mazda RX4: 21          
    # 2 Mazda RX4 Wag: 21      
    # 3 Datsun 710: 22.8       
    # 4 Hornet 4 Drive: 21.4   
    # 5 Hornet Sportabout: 18.7
    # 6 Valiant: 18.1          
    # 7 Duster 360: 14.3       
    # 8 Merc 240D: 24.4        
    # 9 Merc 230: 22.8         
    #10 Merc 280: 19.2         
    # … with 22 more rows
    
    1. With get :
    data %>% 
      mutate(Label=glue("{Vehicle}: {value}",value= get(column_of_interest))) %>% 
      select(Label)
    
    1. Use sym with !! :
    data %>% 
      mutate(Label=glue("{Vehicle}: {value}",value= !!sym(column_of_interest))) %>% 
      select(Label)