0

As part of a larger function, I'm trying to extract unique, non-na values, so I can iterate over that list. In this function, users should be able to input any column name that exists in their dataframe.

In the past, when I've had to convert a user input into a string, x_character <- deparse(substitute(x)) has worked. However, now I get NULL as my output of the below function with the warning of 1: Unknown or uninitialised column: x.

Why is R not recognizing this x_character with the $ operator? It's worked in the past, so I'm not sure if I'm doing something wrong here.

#Sample data
library(dplyr)
my_data <- tibble(level = c(rep(c("1st", "2nd", NA, "3rd"), 4), NA, "2nd"),
                  id = c(1:17, 30),
                  score = c(81:97, 70))

And here's my code:

unique_without_na <- function(data, x) {
  #Pulls out all rows with data in the cut_by argument; drops nas
  x_character <- deparse(substitute(x))
  print(x_character) #just a check
  
  unique_x <- data$x_character[!is.na(data$x_character)] %>% unique()
  unique_x
  
}

unique_without_na(my_data, level) #doesn't work; I've also tried "level" which also fails
unique_without_na(my_data, score) #also doesn't work
J.Sabree
  • 2,280
  • 19
  • 48

2 Answers2

1

Put them in [[ instead of using $

unique_without_na <- function(data, x) {
  #Pulls out all rows with data in the cut_by argument; drops nas
  x_character <- deparse(substitute(x))
  print(x_character) #just a check
  
  unique_x <- data[[x_character]][!is.na(data[[x_character]])] %>% unique()
  unique_x
  
}

unique_without_na(my_data, level)
#> [1] "level"
#> [1] "1st" "2nd" "3rd"
unique_without_na(my_data, score) 
#> [1] "score"
#>  [1] 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 70
mnist
  • 6,571
  • 1
  • 18
  • 41
0

Alternatively with expr and eval we could try something below.
here we can use $ instead of [[

library(rlang)
library(dplyr)

unique_without_na <- function(data, x) {
  #Pulls out all rows with data in the cut_by argument; drops nas
  x_character <- deparse(substitute(x))
  print(x_character) #just a check
  
  unique_x <- eval(expr('$'(data,!!x_character)))[!is.na(eval(expr('$'(data,!!x_character))))] %>% unique()
  unique_x
  
}
unique_without_na(my_data, level)
#> [1] "level"

Created on 2023-01-20 with reprex v2.0.2

output

[1] "1st" "2nd" "3rd"
jkatam
  • 2,691
  • 1
  • 4
  • 12