Can quosures work with base eval

I came across the below code here while reading about how NSE works in R

statss <- function(df, col){
    
    col_q = enquo(col)
    
    # working
    df %>%
        summarise(mean(eval(col_q), na.rm = TRUE)) %>% print
    
    # working
    df %>% 
        filter(eval(col_q) > 100) %>% print
   
   # working
    df %>% 
        mutate(k = eval(col_q) + 100) %>% print
    
    # error
    df %>% 
        select(eval(col_q))
}

statss(mtcars,  hp)

As you can see, base eval is able to evaluate quosures inside summarize, filter and mutate functions but why isn't it working inside select. Usually outside of the dplyr functions, using eval on quosures just returns the quosure back. Can some one explain what is happening in the background

select() and all tidyselect-based functions have special semantics. They are not implemented with the familiar data-masking rules, but instead implement a special DSL. If you pass a complex expression, it is evaluated plainly, without any column in scope, and without any of the rlang mechanism for quosures. See https://www.tidyverse.org/articles/2017/09/erratum-tidyr-0.7.0/ for some more information about the design choices that went into tidyselect.

3 Likes