Using pre-existing character vectors in quasiquotation of an expression with rlang

妖精的绣舞 提交于 2020-01-13 18:11:15

问题


Sometimes when working with dplyr one has a character vector of column names that's to be used to operate on data, for instance:

 cols_of_interest <- c("Petal.Width", "Petal.Length")

In dplyr 0.5.0 and earlier, the recommended approach to this problem was to use the verb_ underscore construct as follows:

library("tidyverse")
my_cols <- c("Petal.Width", "Petal.Length")
iris %>%
  select_(.dots = my_cols)

The verb_ functions are now deprecated in favour of the new tidy evaluation framework (dplyr.tidyverse.org/articles/programming.html) introduced by the rlang library.

As of dplyr 0.7.0 the following works without any special accommodations:

library("tidyverse")
# library("rlang")
my_cols <- c("Petal.Width", "Petal.Length")
iris %>%
  select(my_cols)

Note that in development builds of dplyr, this was not the case

Motivation

Selecting columns in Shiny apps is a good example use case, this is how one could do it using verb_ notation

library("shiny")
library("tidyverse")
library("DT")

shinyApp(
  ui = fluidPage(
    selectInput("cols_to_show",
                "Columns to show",
                choices = colnames(iris),
                multiple = TRUE),
    dataTableOutput("verb_table")
  ),
  server = function(input, output){
    output$verb_table <- renderDataTable({
      iris %>%
        select_(.dots = input$cols_to_show)

    })
  }
)

回答1:


In pre 0.5.0 dplyr the underlying framework for non-standard evaluation was lazyeval and required special consideration for strings. Hadley Wickham released a fundamentally new version of dplyr with a new underbelly called rlang which provides a more consistent framework for non-standard evaluation. This was version 0.70 - here's an explanation of why 0.6.0 was skipped - https://blog.rstudio.org/2017/06/13/dplyr-0-7-0/

The following now works without any special considerations:

library("tidyverse")
my_cols <- c("Petal.Width", "Petal.Length")
iris %>%
  select(my_cols)

Note that the new rlang framework adds the ability to have a vector of naked symbols using quosures

my_quos <- quos(Petal.Width, Petal.Length)
iris %>%
  select(!!!my_quos)

You can read more about programming with dplyr here - http://dplyr.tidyverse.org/articles/programming.html

Comparison in Shiny

library("shiny")
library("tidyverse")
library("DT")
library("rlang")
shinyApp(
  ui = fluidPage(
    selectInput(
      "cols_to_show",
      "Columns to show",
      choices = colnames(iris),
      multiple = TRUE
    ),
    dataTableOutput("verb_table"),
    dataTableOutput("tidyeval_table")
  ),
  server = function(input, output) {
    output$verb_table <- renderDataTable({
      iris %>%
        select_(.dots = input$cols_to_show)

    })

    output$tidyeval_table <- renderDataTable({
      iris %>%
        select(!!!syms(input$cols_to_show))

    })
  }
)



回答2:


With dplyr 0.6, select() now understands both column names and column positions. Previously it would only understand the latter. So you don't need syms() anymore because this now works: select(mtcars, c("cyl", "disp"), "am").



来源:https://stackoverflow.com/questions/43955905/using-pre-existing-character-vectors-in-quasiquotation-of-an-expression-with-rla

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!