使用预先存在的字符向量在带有rlang

时间:2017-05-13 17:17:14

标签: r dplyr rlang tidyeval

有时使用dplyr时,会有一个字符列的字符向量用于操作数据,例如:

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

dplyr 0.5.0及更早版本中,针对此问题的推荐方法是使用verb_下划线构造,如下所示:

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

verb_函数现已弃用,有利于rlang库引入的新的整洁评估框架(dplyr.tidyverse.org/articles/programming.html)。

dplyr 0.7.0开始,以下工作没有任何特殊条件:

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

请注意,在dplyr的开发版本中,情况并非如此

动机

选择Shiny apps中的列是一个很好的示例用例,这就是使用verb_表示法的方法

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)

    })
  }
)

2 个答案:

答案 0 :(得分:3)

在0.5.0 dplyr之前,非标准评估的基础框架为lazyeval,需要特别考虑字符串。 Hadley Wickham发布了一个基本上新版本的dplyr,其中包含一个名为rlang的新下层,为非标准评估提供了更加一致的框架。这是版本0.70 - 这里解释了为什么0.6.0被跳过 - https://blog.rstudio.org/2017/06/13/dplyr-0-7-0/

以下内容现在无需任何特殊注意事项:

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

请注意,新的rlang框架增加了使用quosures获得裸符号向量的功能

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

您可以在此处阅读有关使用dplyr进行编程的更多信息 - http://dplyr.tidyverse.org/articles/programming.html

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))

    })
  }
)

答案 1 :(得分:1)

使用dplyr 0.6,select()现在可以理解列名和列位置。以前它只会理解后者。因此,您现在不再需要syms(),因为现在可以使用select(mtcars, c("cyl", "disp"), "am")