根据按下的操作按钮显示数据输出

Show data output depending on which action button pressed

我正在创建一个闪亮的应用程序,允许用户上传数据并在主面板上显示内容。有两个操作按钮,一个显示一些示例数据,另一个操作按钮显示上传数据文件的内容。如果用户没有上传任何数据文件,那么点击第二个操作按钮应该 return 一条消息说 'please upload data first'。我正在努力实现第二个操作按钮,因此非常感谢您的帮助。

我试过使用 reactiveVal (),但它无法使用第二个操作按钮。我想我需要以某种方式将上传的数据集保存到一个可以通过第二个操作按钮检索的对象中。

library(tidyverse)
library(shiny)
library(shinyWidgets)
library(DT)


options(shiny.maxRequestSize=30*1024^2) 

recommendation <- tibble(Account = c("Axis", "HSBC", "SBI", "ICICI", "Bandhan Bank", "Axis", "HSBC", "SBI", "ICICI", "Bandhan Bank"),
                             Product = c("Bank", "FBB", "FBB", "FBB","FBB","SIMO", "SIMO", "SIMO", "SIMO", "SIMO"),
                             Region = c("North", "South", "East", "West", "West", "North", "South", "East", "West", "West"),
                             Revenue = c(2000, 30000, 1000, 1000, 200, 200, 300, 100, 100, 200))


ui <- fluidPage(

  titlePanel("Example"),


  sidebarLayout(
    sidebarPanel(

      fileInput("Upload", "Upload your own Data"),

      actionButton("Example", "Show Example Data instead"),
      actionButton("data", "Show New data")


    ),

    mainPanel(

      column(DT::dataTableOutput('showdata'), width = 12),

    )
  )
)

# Server Logic
server <- function(input, output) {
  my_data <- reactiveVal()

  observeEvent(input$Upload, {
    tmp <- read.csv(input$Upload$datapath)
    my_data(tmp)
  })

  observeEvent(input$Example, {
    my_data(recommendation)

  })

  observeEvent(input$data, {
    my_data()

  })

  output$showdata = renderDT(my_data(), rownames = FALSE, class = "display nowrap compact", filter = "top",
                           options = list(
                             scrollX = TRUE,
                             scrollY = TRUE,
                             autoWidth = FALSE))

}



# Run the application 
shinyApp(ui = ui, server = server)

点击 'show new data' 操作按钮,应该会显示刚刚上传的数据。但是,如果没有任何上传的数据,则应显示一条消息提示用户上传数据集。

似乎您使用 reactiveVal 的方式是在按下按钮时 returns 一个空值(my_data() returns 什么都没有)。此外,您的服务器代码中不需要第一个 observeEvent,因为这只会在上传文件时更新 my_data,而不是在按下按钮时更新。 我这样做的方法是在按下显示新数据时检查是否有上传的文件,如果有,则显示它。如果没有,提示模态对话框通知用户先上传文件。像这样(只写服务端函数,其余不变):

# Server Logic
server <- function(input, output) {

  my_data <- reactiveVal()

  ## Not need of this, this will be done when pressing the show data button
  # observeEvent(input$Upload, {
  #   tmp <- read.csv(input$Upload$datapath)
  #   my_data(tmp)
  # })

  # Observer to update my_data when example button is pressed
  observeEvent(input$Example, {
    my_data(recommendation)
  })

  # Observer to update my_data when data button is pressed, checking if there
  # is a file uploaded
  observeEvent(input$data, {

    # check if we have a data uploaded
    if (is.null(input$Upload)) {
      # if there is no data uploaded, reset my_data, and show a modal message
      my_data()
      showModal(
        modalDialog(title = 'No data uploaded',
                    'Please upload a file before clicking the button')
      )
    } else {
      # if there is data uploaded, read it and return it
      tmp <- read.csv(input$Upload$datapath)
      my_data(tmp)
    }
  })

  output$showdata = renderDT(my_data(), rownames = FALSE, class = "display nowrap compact", filter = "top",
                             options = list(
                               scrollX = TRUE,
                               scrollY = TRUE,
                               autoWidth = FALSE))

}

检查我的系统并按您的问题预期工作。

编辑

编辑以提供更有效的方式,避免每次读取文件:

# Server Logic
server <- function(input, output) {

  my_data <- reactiveVal()

  ## Not need of this, this will be done when pressing the show data button
  # observeEvent(input$Upload, {
  #   tmp <- read.csv(input$Upload$datapath)
  #   my_data(tmp)
  # })

  # Observer to update my_data when example button is pressed
  observeEvent(input$Example, {
    my_data(recommendation)
  })

  # reactive to store the uploaded data
  data_loaded <- reactive({
    # dont try to read if there is no upload
    shiny::validate(
      shiny::need(input$Upload, 'no data uploaded')
    )
    # read the file
    read.csv(input$Upload$datapath)
  })

  # Observer to update my_data when data button is pressed, checking if there
  # is a file uploaded
  observeEvent(input$data, {

    # check if we have a data uploaded
    if (is.null(input$Upload)) {
      # if there is no data uploaded, reset my_data, and show a modal message
      my_data()
      showModal(
        modalDialog(title = 'No data uploaded',
                    'Please upload a file before clicking the button')
      )
    } else {
      # if there is data uploaded, read it and return it
      tmp <- data_loaded()
      my_data(tmp)
    }
  })

  output$showdata = renderDT(my_data(), rownames = FALSE, class = "display nowrap compact", filter = "top",
                             options = list(
                               scrollX = TRUE,
                               scrollY = TRUE,
                               autoWidth = FALSE))

}