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

时间:2019-11-09 00:41:05

标签: r shiny shinyapps

我正在创建一个闪亮的应用程序,它将允许用户上传数据并在主面板上显示内容。有两个操作按钮,一个用于显示示例数据,另一个用于显示上载数据文件的内容。如果用户尚未上传任何数据文件,则单击第二个操作按钮应返回一条消息,“请先上传数据”。我正在努力实现第二个操作按钮,因此非常感谢您的帮助。

我尝试使用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)

点击“显示新数据”操作按钮,应显示刚刚上传的数据。但是,如果没有任何上传的数据,则应显示一条消息提示用户上传数据集。

1 个答案:

答案 0 :(得分:1)

似乎按下按钮时您使用reactiveVal的方式返回一个空值(my_data()不返回任何值)。另外,服务器代码中不需要第一个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))

}