Non-standard evaluation and quasiquotation in dplyr() not working as (naively) expected

前端 未结 2 2094
自闭症患者
自闭症患者 2020-12-11 08:32

I am trying to search a database and then label the ouput with a name derived from the original search, \"derived_name\" in the reproducible example below. I am

相关标签:
2条回答
  • 2020-12-11 09:02

    So, I've realized that what I was struggling with in this question (and many other probelms) is not really quasiquotation and/or non-standard evaluation, but rather converting character strings into object names. Here is my new solution:

    letrs_top.df <- letrs_count.df %>%
        top_n(5, get(count_colname))
    
    0 讨论(0)
  • 2020-12-11 09:03

    According to top_n documentation (?top_n), it doesn't support character/string input thus the 1st example didn't work. In your 2nd example, rlang::sym converted the string to a variable name then !! unquoted it so that it could be evaluated inside top_n. Note: top_n and other dplyr verbs automatically quote their inputs.

    Using rlang::qq_show as suggested by @lionel, we can see it doesn't work because there is no count_colname column in letrs_count.df

    library(tidyverse)
    
    set.seed(1)
    letrs <- letters[rnorm(52, 13.5, 5)]
    letrs_count.df <- letrs %>%
      table() %>%
      as.data.frame()
    
    search_name <- "derived_name"
    count_colname <- paste0(search_name, "_letr_count")
    colnames(letrs_count.df) <- c("letr", count_colname)
    letrs_count.df
    #>    letr derived_name_letr_count
    #> 1     b                       1
    #> 2     c                       1
    #> 3     f                       2
    ...
    
    rlang::qq_show(top_n(letrs_count.df, 5, count_colname))
    #> top_n(letrs_count.df, 5, count_colname)
    

    sym & !! create the right column name existing in letrs_count.df

    rlang::qq_show(top_n(letrs_count.df, 5, !! sym(count_colname)))
    #> top_n(letrs_count.df, 5, derived_name_letr_count)
    
    letrs_count.df %>%
      top_n(5, !! sym(count_colname))
    #>   letr derived_name_letr_count
    #> 1    l                       5
    #> 2    m                       6
    #> 3    o                       7
    #> 4    p                       5
    #> 5    q                       6
    

    top_n(x, n, wt)

    Arguments:

    • x: a tbl() to filter

    • n: number of rows to return. If x is grouped, this is the number of rows per group. Will include more than n rows if there are ties. If n is positive, selects the top n rows. If negative, selects the bottom n rows.

    • wt: (Optional). The variable to use for ordering. If not specified, defaults to the last variable in the tbl. This argument is automatically quoted and later evaluated in the context of the data frame. It supports unquoting. See vignette("programming") for an introduction to these concepts.

    See also these answers: 1st, 2nd, 3rd

    0 讨论(0)
提交回复
热议问题