How to create a function with "not equal to"?

Viewed 115

I have a function that I'm trying to create using filter !=, but it doesn't work. I wonder if it is due to something related with tidy evaluation.

This is what I tried:

library(haven)
library(dplyr)
library(labelled)
library(sjlabelled)

data <- read_spss("http://staff.bath.ac.uk/pssiw/stats2/SAQ.sav")
data$Q01_L <- as_label(data$Q01)

This is the function I tried to write:

    bar_plot <- function(data, var) {
      var <- rlang::ensym(var)
      
      data %>% 
        filter(!var == "Neither") %>% 
        ggplot(aes(!!var)) +
        geom_bar() +
        coord_flip() +
        theme_classic() +
        labs(x = "Question", y = "Count", title = var_label(data$var)) 
    }
    
    
    bar_plot(data, Q01_L)

What I am trying to achieve is to remove "Neither" values and I tried this using filter(!var == "Neither") but that doesn't work and I'm still getting "Neither" plotted. And I also lost the title of the chart.

enter image description here

This is what I'm trying to achieve:

enter image description here

I was able to do this with a few lines of code:

data %>% 
  filter(!Q01_L == "Neither") %>% 
  ggplot(aes(Q01_L)) +
  geom_bar() +
  coord_flip() +
  theme_classic() +
  labs(x = "Question", y = "Count", title = var_label(data$Q01_L)) 

But I'm not able to figure out how to convert it into a function.

3 Answers

enter image description here

Try eval as filter(!eval(var) == "Neither")

 bar_plot <- function(.data, var) {
    var <- rlang::ensym(var)
    
    data %>% 
        filter(!eval(var) == "Neither") %>% 
        ggplot(aes(!!var)) +
        geom_bar() +
        coord_flip() +
        theme_classic() +
        labs(x = "Question", y = "Count", title = var_label(data[var])) 
}


bar_plot(data, Q01_L)

You can also use !! (credits @DarrenTsai) and !=:

#Plot
bar_plot <- function(.data, var) {
  var <- rlang::ensym(var)
  
  data %>% 
    filter(!!var != "Neither") %>% 
    ggplot(aes(!!var)) +
    geom_bar() +
    coord_flip() +
    theme_classic() +
    labs(x = "Question", y = "Count", title = var_label(data[,var])) 
}


bar_plot(data, Q01_L)

Output:

enter image description here

You can use the curly-curly operator in a function, so that var <- rlang::ensym(var) can be removed.

From help("nse-force"):

The curly-curly operator {{ }} for function arguments is a bit special because it forces the function argument and immediately defuses it. The defused expression is substituted in place, ready to be evaluated in another context, such as the data frame.

bar_plot <- function(data, var) {
  
  data %>% 
    filter({{var}} != "Neither") %>% 
    ggplot(aes( {{var}} )) +
    geom_bar() +
    coord_flip() +
    theme_classic() +
    labs(x = "Question", y = "Count", title = var_label(pull(data, {{var}})))
}

bar_plot(data, Q01_L)
Related