2
votes

I have a shiny app that takes a csv file that looks like this:

category
action

and inputs it into the dataframe to filter the category with only "action".

Reproducible APP:

UI:

library(shiny)
shinyUI(fluidPage(
  titlePanel("Actor Finder"),
  sidebarLayout(
    sidebarPanel(
      fileInput("file","Upload Category List: Must have category as header"),
      selectInput("file4", "Select Type", c("A" = "A",
                                               "B" = "B",
                                               "C" = "C"), selected = "A"),
      numericInput("file5", "Choose cost", 1000000000),
      tags$hr()),    
    mainPanel(
      uiOutput("tb")
    )

  )
))

Server:

library(shiny)
library(readr)
library(dplyr)
# use the below options code if you wish to increase the file input limit, in this example file input limit is increased from 5MB to 9MB
# options(shiny.maxRequestSize = 9*1024^2)

actor <- c('Matt Damon','George Clooney','Brad Pitt', 'Clive Owen', 'Morgan Freeman', 'Edward Norton', 'Adrian Granier')
category<-c('action', 'action', 'noir', 'action', 'thriller', 'noir', 'action')
movie <- c('Oceans Eleven', 'Oceans Twelve', 'Fight Club', 'Children of Men', 'The Shawshank Redemption', 'American History X', 'Entourage')
movies <- c(21, 23, 26, 12, 90, 14, 1)
cost <- c(210000, 2300000, 260000, 120000, 90000, 140000, 10000)
Type <- c('A','B','C', 'A', 'B', 'C', 'A')

moviedata<-data.frame(actor, category, movie, movies, cost, Type)

# This reactive function will take the inputs from UI.R and use them for read.table() to read the data from the file. It returns the dataset in the form of a dataframe.
# file$datapath -> gives the path of the file

shinyServer(function(input,output){
data <- reactive({
  file1 <- input$file
  if(is.null(file1)){return()} 
  read_csv(file=file1$datapath)

})


# this reactive output contains the summary of the dataset and display the summary in table format

# this reactive output contains the summary of the dataset and display the summary in table format
output$sum <- renderTable({
  if(is.null(data())){return ()}
  test<-subset(moviedata, category %in% data())
  test1<-filter(test, `Type`==input$file4)
  test1$`BUDGET`<-input$file5
  test1$CHECKING<-ifelse(test1$`BUDGET`>test1$cost,"YES", "NO")
  filter(test1, CHECKING=="YES")
})

 # the following renderUI is used to dynamically generate the tabsets when the file is loaded. Until the file is loaded, app will not show the tabset.
output$tb <- renderUI({
  if(is.null(data()))
    h5("Powered by", tags$img(src='optimatic.png'))
  else
    tabsetPanel(tabPanel("Summary", tableOutput("sum")))
})

} 
)

I want to be able to do the following:

The output looks like this:

enter image description here

1) Add a download button to the renderTable dataframe. So let's say I change the filters for the new output in the UI, then I want to be able to download that new output.

2) Change the format of the dataframe to a dataTable from the DT package.

Any help would be great, thanks!

1
For 1) I suggest storing the filtered data in a reactive() function or reactiveValues() with stackoverflow.com/questions/30042456/…. 2) You simply ask for the DT::renderDataTable() function? - Tonio Liebrand
I tried doing the DT::renderDataTable() but I got an error. Do I need to do anything else with that function besides adding the DT:: in front of renderDataTable()? Also can you please provide a reproducible answer so I can test it out. I am very much new to this. Also if anything, the most important answer out of this is to figure out the download button. Thanks for the feedback! - nak5120
Hi @Nick, then I guess you forgot to adapt the code on ui side. Did you change it to dataTableOutput()? Reproducible makes sense as soon as he problem is clear :). - Tonio Liebrand
I did not, I kept it as uiOutput. Should I change it to that? I haven't really changed anything from the code above yet. @TonioLiebrand - nak5120

1 Answers

3
votes

It's very easy to use DT:

1 - load the package:

library(DT)

2- render your table by replacing renderTable with renderDataTable (specifying exptension argument to include download button):

output$sum <- renderTable({...}, 
  extensions = c('Buttons'), 
  options = list(
    dom = 'Bfrtip',
    buttons = c('copy', 'csv', 'excel', 'pdf', 'print')
  ))

3- output the result using dataTableOutput instead of tableOutput in the renderUI:

tabsetPanel(tabPanel("Summary", dataTableOutput("sum")))