简体   繁体   中英

How to create a Shiny-app that selects from multiple dfs, edits one and downloads edited data

I try to create a shiny app in which one can choose from different dfs. Then one can edit values in the table. At last I would like to download the edited table.

Each step for itself, edit and download, select and download is no problem. All three together: great despair.

I don't seem to understand how Shiny updates the reactive values and how you can cut it off with isolate.

library(shiny)
library(DT)


ui <- fluidPage(
  
  # App title ----
  titlePanel("Downloading Data"),
  
  # Sidebar layout with input and output definitions ----
  sidebarLayout(
    
    # Sidebar panel for inputs ----
    sidebarPanel(
      
      # Input: Choose dataset ----
      selectInput("dataset", "Choose a dataset:",
                  choices = c("rock", "pressure", "cars"), multiple=T),
      actionButton(inputId   = "goButton",
                   label     = "Run Report"),
      
      # downloadbutton
      downloadButton("downloadData", "Download")
      
    ),
    
    # Main panel for displaying outputs ----
    mainPanel(
      DTOutput("x1")
    )
  )
)

#df <- cars #if this is taken instead of the first "eventReactive" it works

server <- function(input, output) {
   eventReactive({
    
    # Take a dependency on input$goButton
     input$goButton

    # Use isolate() to avoid dependency on input$obs
     df <-  isolate(input$dataset)
  })

  
  #render the editable DT
  
  output[["x1"]] <- renderDT({
    datatable(
      df,
      selection = "single", 
      editable = TRUE
    )
  })
  
  
  
  # Creating a DF with the edited info
  
  aniRoi2 <- reactiveVal(df)
  
  #Creating proxy
  
  proxy <- dataTableProxy("x1")
  
  #storing edited df in proxy
  
  observeEvent(input[["x1_cell_edit"]], { 
    info <- input[["x1_cell_edit"]]
    newAniroi2 <- 
      editData(aniRoi2(), info, proxy, rownames = TRUE, resetPaging = FALSE)
    aniRoi2(newAniroi2)
    saveRDS(newAniroi2, "data_entry_form.rds") # save rds
  })
  
  
  
  #download the proxy
  
  output$downloadData <- downloadHandler(
    filename = function() {
      paste("data-", Sys.Date(), ".csv", sep="")
    },
    content = function(file) {
      write.csv(aniRoi2(), file)
    }
  )
  
  
}

shinyApp(ui, server)

Here I try to select a dataset, that only gets loaded by press of a button. Then it should behave like a normal data.frame or tibble.

If I take out the possibilty of selection of dataframes and call between "ui" and "server" "df <- cars" then it works as intended.

As of now I get the error message: Listening on http://127.0.0.1:4060 Warnung: Error in is_quosure: Argument "expr" fehlt (ohne Standardwert) 52: is_quosure 51: exprToQuo 50: eventReactive 49: server [#2] 3: runApp 2: print.shiny.appobj 1: Error in is_quosure(expr): Argument "expr" fehlt (ohne Standardwert)

Thank you very much, any help would be much appreciated. It feels as if I am so close (but it feels like that since a week).

I also tried this download edited data.table gives warning in shiny app it uses observe to wrap the selection. But in the shiny-app I get the familiar "Error 'data' must be 2-dimensional (eg data frame or matrix)"

PS: If you would forgive a bonus question: How do you debug shiny? I mean how can you see inside of what is happening, how the environment looks like and which processes are working?

There are some issues with your code. First, input$dataset is a character string with the name of the chosen dataset, not the dataset itself. To get the dataset use eg get(input$dataset) . Second, the way you use eventReactive is interesting. (; Overall I would go for an observeEvent to init your reactiveVal aniRoi2 with the chosen dataset. Finally I have set multiple=FALSE in your selectInput as choosing multiple df's breaks your code and allowing the user to select multiple dfs makes no sense to me. (I guess that you have done this to get rid of the pre-selected value?? )

library(shiny)
library(DT)

ui <- fluidPage(
  titlePanel("Downloading Data"),
  sidebarLayout(
    sidebarPanel(
      selectInput("dataset", "Choose a dataset:",
        choices = c("rock", "pressure", "cars"), multiple = FALSE
      ),
      actionButton(
        inputId = "goButton",
        label = "Run Report"
      ),
      downloadButton("downloadData", "Download")
    ),
    mainPanel(
      DTOutput("x1")
    )
  )
)

server <- function(input, output) {
  aniRoi2 <- reactiveVal()
  
  observeEvent(input$goButton, {
    aniRoi2(get(input$dataset))
  })

  output[["x1"]] <- renderDT({
    datatable(
      aniRoi2(),
      selection = "single",
      editable = TRUE
    )
  })

  proxy <- dataTableProxy("x1")

  observeEvent(input[["x1_cell_edit"]], {
    info <- input[["x1_cell_edit"]]
    newAniroi2 <-
      editData(aniRoi2(), info, proxy, rownames = TRUE, resetPaging = FALSE)
    aniRoi2(newAniroi2)
  })

  output$downloadData <- downloadHandler(
    filename = function() {
      paste("data-", Sys.Date(), ".csv", sep = "")
    },
    content = function(file) {
      write.csv(aniRoi2(), file)
    }
  )
}

shinyApp(ui, server)

在此处输入图像描述

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM