问题
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