R - Download Filtered Datatable

R - Download Filtered Datatable

If you use client side processing, you can accomplish this with the input object input[["tablename_rows_all"]]. (append _rows_all to the name of the datatable output slot)

The _rows_all object will return the row indices of your data frame. You can use that within your downloadHandler to subset the data frame when the download is initiated.

library(shiny)
library(DT)

shinyApp(
ui =
shinyUI(
fluidPage(
DT::dataTableOutput("dt"),

p("Notice that the 'rows_all' attribute grabs the row indices of the data."),
verbatimTextOutput("filtered_row"),

downloadButton(outputId = "download_filtered",
label = "Download Filtered Data")
)
),

server =
shinyServer(function(input, output, session){
output$dt <-
DT::renderDataTable(
datatable(mtcars,
filter = "top"),
server = FALSE
)

output$filtered_row <-
renderPrint({
input[["dt_rows_all"]]
})

output$download_filtered <-
downloadHandler(
filename = "Filtered Data.csv",
content = function(file){
write.csv(mtcars[input[["dt_rows_all"]], ],
file)
}
)
})
)

R + Shiny + DT : download filtered data

Here is a way with a datatables button, not with a download handler:

  output$table <- renderDT({
datatable(
df_filter(),
extensions = "Buttons",
options = list(
dom = "Bfrtip",
buttons = list(
list(
extend = "csv",
exportOptions = list(
modifier = list(
search = "applied"
)
)
)
)
)
)
}, server = FALSE)

download filtered data of a dataTable in Shiny

I have tweaked the code minimally. First I used mtcars instead of my_data.
I think the main issue is to Set server = FALSE in the renderDT function (learned here @Stéphane Laurent) R shiny datatable extension "Buttons" - how to export the whole table to excel?:

library(shiny)
library(DT)

ui <- fluidPage(
downloadButton("download_filtered", "Download filtered dataset"),

verbatimTextOutput("filtered_row"),
DT::dataTableOutput("fancyTable"),
tags$hr(),
plotOutput("fancyPlot")
)

server <- function(input, output, session) {
output$fancyTable <-
DT::renderDT({
datatable(mtcars,
filter = "top",
extensions = "Buttons",
options = list(paging = TRUE,
scrollX=TRUE,
searching = TRUE,
ordering = TRUE,
dom = 'l<"sep">Bfrtip',
buttons = c('copy', 'csv', 'excel', 'pdf'),
pageLength=10,
lengthMenu=c(10,20,50,100)
)
)
}, server = FALSE
)

output$filtered_row <- renderPrint({
input[["fancyTable_rows_all"]]
})

output$download_filtered <- downloadHandler(
filename = "Filtered Data.csv",
content = function(file){
write.csv(my_data[input[["fancyTable_rows_all"]], ],
file)
}
)
}

shinyApp(ui, server)

Sample Image

Download filtered data from renderDataTable() in Shiny

Replicating the example from the link you provided it seems to work.

You just need to replace

output$downLoadFilter <- downloadHandler(
filename = function() {
paste('Filtered data-', Sys.Date(), '.csv', sep = '')
},
content = function(file){
write.csv(thedata(),file)
}
)

in your server with

 output$downLoadFilter <- downloadHandler(
filename = function() {
paste('Filtered data-', Sys.Date(), '.csv', sep = '')
},
content = function(file){
write.csv(thedata()[input[["ex1_rows_all"]], ],file)
}
)

That does the trick. Hope it helps!

Downloadhandler with filtered data in Shiny

Nice app. Your issue is mainly that thedata() is a DT::datatable and not the actual data. I've reworked it which now works for me, see comments in the script:

library(shiny)
library(ggplot2)
library(DT)
library(readr)

tbl <- read.csv(file.choose(new = FALSE), header = TRUE, sep = ",", stringsAsFactors=TRUE)

# Define UI ----
ui <- navbarPage(
title = "Data Table Options",

tabPanel("Lot Dataset",
DT::dataTableOutput("dt"), #datatable

div(h3("Download"), style = "color:blue"),
helpText(" Select the download format"),
radioButtons("type", "Format type:",
choices = c("Excel (CSV)", "Text (Space Separated)", "Doc")),
br(),
helpText(" Click on the download button to download the Lot Dataset"),
p("Below are the row indices of the data."),
verbatimTextOutput("filtered_row"),
br(),
helpText(" Click on the download button to download the Lot Dataset"),
downloadButton("download_filtered", "Download Filtered Data"),
br()
)
)

server <- function(input, output) {

#!! I've moved the datatable directly in here as 'thedata()' was a bit redundant and confusing
output$dt <- DT::renderDataTable({
datatable(tbl,filter = "top",options = list(pageLength = 25))
})

#bottom panel with row indices
output$filtered_row <-
renderPrint({
input[["dt_rows_all"]]
})

#file extension for download
fileext <- reactive({
switch(input$type,
"Excel (CSV)" = "csv", "Text" = "txt", "Doc" = "doc")
})

#downloadHandler() for file download of Lot Dataset
output$download_filtered <- downloadHandler(

filename = function() {
paste("MLdataset_test", fileext(), sep=".") #filename
},

content = function(file) {

#!! Use tbl and not 'thedata()' to filter. tbl is the data, the other was the datatable
write.csv(tbl[input[["dt_rows_all"]], ],
file= file,
#!! assumed we don't want the row names
row.names=F)
}
)

}

shinyApp(ui, server)

Save filtered DT::datatable into a new dataframe R shiny

Maybe this type of solution. It is possible to add further conditions like checking the first letter in upper case, but the main idea is to check each column and search for the pattern entered inside the datatable searchbox. This may or may not result in more than one dataset to print (depending if the string is partially matched in multiple columns (this is also solvable with rbind function.

code:

library(shiny)
library(tidyverse)
library(datasets)
library(DT)
data <- as.data.frame(USArrests)
data <- cbind(state = rownames(data), data)
ui <- fluidPage(
dataTableOutput("preview"),
tableOutput('filtered_df')
)

# Define server logic required to draw a histogram
server <- function(input, output) {

df <- reactiveValues()

output$preview<- renderDataTable(
datatable(data, options = list(searching = T, pageLength = 10, lengthMenu = c(5,10,15, 20), scrollY = "600px", scrollX = T ))
)

observeEvent(input$preview_search, {
searched_string <- map(data, ~str_subset(.x, input$preview_search)) %>% discard(~length(.x) == 0)

df$filtered <- syms(names(data)) %>%
map(~ filter(data, !!.x %in% searched_string)) %>%
discard(~ nrow(.x) == 0)



})

output$filtered_df <- renderTable({df$filtered})

}

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

Problem with Shiny downloadHandler - Won't Download Filtered Data as Displayed on Screen

You are not using the reactive object the correct way. In shiny, the idea behind that type of objects is to avoid repeating yourself. Here you can create a reactive object reactiveDF and use that one to generate the dataTableOutput and the download table.

library(shiny)
library(DT)
library(ggplot2)

## === LOAD EXAMPLE DATA =====

cars = mtcars

# do I make the data frame reactive?

## ==== UI ====

ui <- fluidPage(
titlePanel("Basic DataTable"),

# Create a new Row in the UI for selectInputs
fluidRow(
column(4,
selectInput("cyl",
"Cylinders:",
c("All",
unique(sort(as.character(cars$cyl)))))
),
column(4,
selectInput("gear",
"Gears:",
c("All",
unique(as.character(cars$gear))))
),
column(4,
selectInput("carb",
"Carburators:",
c("All",
unique(as.character(cars$carb))))
)
),
# Create a new row for the table.

DT::dataTableOutput("dt"),

p("Notice that the 'rows_all' attribute grabs the row indices of the data."),
verbatimTextOutput("filtered_row"),

# Create a new row for the download button
p("The table responds to the filters perfectly, yet it will not download the data. Test it out."),
p("Evaluate the csv file and you will see that while it extracts the filtered rows,"),
p("it is not displaying the actual filtered data in the table!"),

downloadButton(outputId = "download_filtered",
label = "Download Filtered Data")
)

## ==== END UI ====

## ==== SERVER ====

server = function(input, output){


reactiveDF = reactive({
cardata <- cars
# conditionals

if (input$cyl != "All") {
cardata <- cardata[cardata$cyl == input$cyl, ]
}
if (input$gear != "All") {
cardata <- cardata[cardata$gear == input$gear, ]
}
if (input$carb != "All") {
cardata <- cardata[cardata$carb == input$carb, ]
}

# display the filtered data
cardata


})

output$filtered_row <-
renderPrint({
input[["dt_rows_all"]]
})

# Filter data based on selections

# This controls the 3 filters displayed on top of the datatable
output$dt <- DT::renderDataTable(datatable({
reactiveDF()
}))



# Download handler for exporting the data to csv -this won't work as intended -----

output$download_filtered <-
downloadHandler(
filename = "filtered_report.csv",
content = function(file){
write.csv(reactiveDF(),file)
}
)
}

shinyApp(ui,server)

r shiny download filtrered datatables (DT)

I think this is because the search filter is done on the client's side (within the web browser) and it does not really change the underlying data frame. A possible alternative is to add a filter to the table and use that as search function, and also set server side processing. This won't do global searching in one box though.

output$data <- DT::renderDataTable(
df$data, server = TRUE, filter = 'top', escape = FALSE, selection = 'none'
)


Related Topics



Leave a reply



Submit