R Shiny 添加用户反馈功能

本章节主要内容是如何实现包括确认,取消在内的用户反馈操作。

内容流程是先介绍validation,用来让用户确认自己的输入。然后是介绍注意 notification ,用来编辑注意⚠️警告文。然后是progress bars ,这个是用来展示进度还有时间耗费。最后会介绍confirmationundo 的操作,用来确认和取消操作。

本章节主要是用shinyFeedback 包来实现以上的操作。

1 Validation验证

1.1 验证输入Input

具体操作大概分成两步。2 steps.

首先要在ui里加入useShinyFeedback() 。这一步的作用是自动设置需要的HTML和JAVA脚本。

ui <- fluidPage(
  shinyFeedback::useShinyFeedback(),
  numericInput("n", "n", value = 10),
  textOutput("half")
)

然后需要在server端设置反馈信息。种类分成feedback, feedbackWarning, feedbackDanger, feedbackSuccess。不管是哪一种包含三个参数信息。

  • inputId: feedback对象的ID
  • show:有关是否要展示feedback信息的一个逻辑变量
  • text: 需要展示的feedback信息

还有coloricon 参数可以设置,详细信息可以参考帮助文件。

server <- function(input, output, session) {
  half <- reactive({
    even <- input$n %% 2 == 0
    # inputID= "n" 
    # show= !even
    # text= "Please select an even number"
    shinyFeedback::feedbackWarning("n", !even, "Please select an even number")
    input$n / 2    
  })
  
  output$half <- renderText(half())
}

shinyApp(ui, server)

上面的代码虽然成功显示了警告文,但还是运行了代码给出了结果。理想的情况是不运行。可以用到之前提过的req() 函数。 之前文章里没有说明这是什么函数,其实是”require”的缩写。

server <- function(input, output, session) {
  half <- reactive({
    even <- input$n %% 2 == 0
    shinyFeedback::feedbackWarning("n", !even, "Please select an even number")
    req(even)
    input$n / 2    
  })
  
  output$half <- renderText(half())
}

1.2 用req()取消代码执行

如果想实现在没有任何操作的情况下不显示任何信息,可以用req()函数。

通常在下面的三个情况下可能会用到

  • textInput(), 设置默认输入是value=””,这个时候不会在有输入前跳出任何信息
  • selectInput(),可以创建一个空白选项
  • fileInput() ,在有输入之前就是一个空白项

举个例子,如果不用req() 就会显示错误信息,虽然不会影响整体,但是不美观。

ui <- fluidPage(
  selectInput("language", "Language", choices = c("", "English", "Maori")),
  textInput("name", "Name"),
  textOutput("greeting")
)

server <- function(input, output, session) {
  greetings <- c(
    English = "Hello", 
    Maori = "Kia ora"
  )
  output$greeting <- renderText({
    paste0(greetings[[input$language]], " ", input$name, " !")
  })
}

加入req() 以后就可以解决。 不符合逻辑要求的话所有下游的计算都会被取消。

server <- function(input, output, session) {
  greetings <- c(
    English = "Hello", 
    Maori = "Kia ora"
  )
  output$greeting <- renderText({
    req(input$language, input$name)
    paste0(greetings[[input$language]], " ", input$name, "!")
  })
}

req() 有好几种用法,一种就是刚才的req(input$x) ,只有指定数值以后才执行接下来的代码。还有一种是req(input$a > 0) 添加逻辑判断函数。

1.3 req()和验证

结合req() 和验证可以实现比较复杂的功能。比方说在输入错误的时候不要显示空白,而是把结果显示停留在之前的结果上。可以用到exists 函数来根据数据集是否存在的逻辑结果来激活feedbackDanger,流程归纳一下就是如下:

输入datasets名字,req() 确认到输入以后执行操作,确认datasets名字存在,不存在的话发出警告文,并且cancel output。让结果停留在之前。

ui <- fluidPage(
  shinyFeedback::useShinyFeedback(),
  textInput("dataset", "Dataset name"), 
  tableOutput("data")
)
server <- function(input, output, session) {
  data <- reactive({
    req(input$dataset)
    exists <- exists(input$dataset, "package:datasets")
    shinyFeedback::feedbackDanger("dataset", !exists, "Unknown dataset")
    req(exists, cancelOutput = TRUE)

    get(input$dataset, "package:datasets")
  })
  
  output$data <- renderTable({
    head(data())
  })
}

get() 函数https://rdrr.io/r/base/get.html

1.4 Validate輸出

尽管之前介绍的shinyFeedback看上去很有用,但是在面对多个错误的复杂条件的情况下也会显得无能为力,这时候就要用到validate()函数了。

举个例子,我们需要计算一个输入值的平方,对数,开根号值。需要对数和开根号计算时对于小于0的输入值报错。

注意一下switch的用法。

ui <- fluidPage(
  numericInput("x", "x", value = 0),
  selectInput("trans", "transformation", 
    choices = c("square", "log", "square-root")
  ),
  textOutput("out")
)

server <- function(input, output, session) {
  output$out <- renderText({
    if (input$x < 0 && input$trans %in% c("log", "square-root")) {
      validate("x can not be negative for this transformation")
    }
    
    switch(input$trans,
      square = input$x ^ 2,
      "square-root" = sqrt(input$x),
      log = log(input$x)
    )
  })
}

你可能感兴趣的:(R Shiny 添加用户反馈功能)