5.8 shiny中的整洁式编程

5.8.1 Data-masking

由于shiny通过input来获取输入信息,其中不乏在数据框中需要用到的变量名。但由于不是直接输入对应的变量名,而是依靠input$variable的形式调用,所以会出现意料之外的结果。对此,需要区分环境中的变量数据框中的变量这两种变量。前者需要用.env$var来声明,后者用.data$var声明。

我们想根据输入的变量名及最小值来筛选数据。第一种写法就会出现意料之外的结果,第二种写法才符合预期。

# 第一种
data <- reactive(diamonds %>% filter(input$var > input$min))

# 第二种
data <- reactive(diamonds %>% filter(.data[[input$var]] > .env$input$min))

环境中有inputinput中有min,故可写作.env$input$min;数据框中没有input,故.data$input$var的写法错误

5.8.2 Tidy-selection

同理,tidy风格下的select之类的函数都可以直接输入变量名来进行操作。因此需要进行转化。all_of()any_of()适合把字符串向量转化为适合tidy风格的变量。

all_of()会严格要求字符串向量中的变量都在要提取的对象之中。没有的话就会报错。

any_of()比较随和,有就提取,没的话就算了。

指的是字符串向量中的变量名是否在数据框中

output$data <- renderTable({
    req(input$vars)
    mtcars %>% select(all_of(input$vars))
  })
output$count <- renderTable({
    req(input$vars)
    mtcars %>% 
      group_by(across(all_of(input$vars))) %>% 
      summarise(n = n(), .groups = "drop")
  })