Simply put, I'd like my app to allow the user to filter images with certain characteristics and consequently allow them to download the selected images into a zip file. The images are stored locally.
I've been able to add the images as thumbnails and allow the user to download the data associated with it (as a .csv) but not the actual images.
Here's what I have:
df <- read.csv("./imagedata.csv")
thumbnails <- list.files(path = "./localstore/", pattern = NULL, all.files = FALSE,
full.names = F, recursive = FALSE,
ignore.case = FALSE, include.dirs = FALSE, no.. = FALSE)
thumbnail_path = "./localstore/"
#----------------------------------Process Thumbnnail----------------------------------#
steps <- 0
out <- vector(mode = "list", length = nrow(df))
for (i in df$Thumbnail) {
out[i] <- knitr::image_uri(i)
steps <- steps + 1
}
print(steps)
ProcessedIcon <- as.data.frame(unlist(out))
Icon <- paste("<img src=", ProcessedIcon$`unlist(out)` ,"></img>", sep = "")
df_Icon <- cbind(df, Icon)
#--------------------------------------- UI ---------------------------------------#
ui <- dashboardPage(
skin = "green",
dashboardHeader(title = span(img(src = "logo.png", height = 35), img(src = "logo2.png", height = 35))),
dashboardSidebar(
sidebarMenu(
menuItem("Item Category", tabName = "category", icon = icon("file"),
selectInput(inputId = "ItemCategory",
label = "",
choices = unique(df$ItemCategory),
selected = unique(df$ItemCategory),
multiple = TRUE,
selectize = TRUE,
width = NULL,
size = NULL)
),
menuItem("Item Sub-category", tabName = "subcategory", icon = icon("copy"),
selectInput(inputId = "ItemSubCategory",
label = "",
choices = unique(df$SubCategory),
selected = unique(df$SubCategory),
multiple = TRUE,
selectize = TRUE,
width = NULL,
size = NULL)
),
br(),
br(),
column(11, align = "center",
downloadButton("downloadData", "Download Data"), class = "butt"),
tags$head(tags$style(".butt{font:black;}")),
br(),
br(),
column(11, align = "center",
downloadButton("downloadImages", "Download Images"), class = "butt"),
tags$head(tags$style(".butt{font:black;}"))
)
),
dashboardBody(
DT::dataTableOutput('dftable'),
)
)
#--------------------------------------- Server ---------------------------------------#
server <- function(input, output) {
#------------------------------------Download table-------------------------------#
Info_Database <- reactive ({
df %>%
filter(ItemCategory %in% c(input$ItemCategory)) %>%
filter(SubCategory %in% c(input$ItemSubCategory)) %>%
select(-Thumbnail)
})
#------------------------------------Display table-------------------------------#
table <- reactive ({
df_Icon %>%
select(Icon, ItemCategory, SubCategory, QualityOfImage, Recognisability)%>%
filter(ItemCategory %in% c(input$ItemCategory)) %>%
filter(SubCategory %in% c(input$ItemSubCategory)) %>%
})
output$dftable <- DT::renderDataTable({
DT::datatable(table(), escape = FALSE, options = list(scrollX = TRUE))
})
# download handler- Database
output$downloadData <- downloadHandler(
filename = function() {
paste('ImageDatabase_', Sys.Date(), '.csv', sep='')
},
content = function(con) {
write.csv(Info_Database(), con)
}
)
# here's where I'm totally lost
# download handler- Images
#output$downloadImages <- downloadHandler(
#)
}
imagedata.csv should look like:
ItemCategory
SubCategory
QualityOfImage
Recognisability
Animal
Cat
5
4
Animal
Dog
4
3
Food
Banana
3
4
Objects
House
5
5
Display table should look like:
Icon
ItemCategory
SubCategory
QualityOfImage
Recognisability
Animal
Cat
5
4
Animal
Dog
4
3
Food
Banana
3
4
Objects
House
5
5
First things first
A reprex would tremendously increase your chances of getting an answer, because nobody wants first to re-create your data structure first to be able to help you.
Aproach
I would follow a slightly different approach. Rather than encoding the pictures, I would use an <img> tag to include them.
Setup
N.B. All My SO answers are sitting in Project Root - this is not important for this solution, but necessary to re-run the example. Pics are taken from your example.
Project Root
|- .Rproj
|- Download
|- app.R
|- www
|- pic-1.jpg
|- pic-2.png
|- pic-3.png
|- pic-4.jpg
app.R
library(shiny)
library(tibble)
library(DT)
library(dplyr)
library(here)
library(purrr)
all_pics <- list.files(here("Download", "www"), pattern = "\\.jpg$|\\.png$")
my_data <- tibble(Icon = all_pics,
ItemCategory = c("Animal", "Objects", "Objects", "Animal"),
SubCategory = c("Cat", "Banana", "House", "Dog"))
ui <- fluidPage(
titlePanel("Download Pics and Table"),
sidebarPanel(
selectInput("category", "Category:",
c("All", my_data %>% pull(ItemCategory)),
"All"),
downloadButton("dwnld_data", "Download Data"),
downloadButton("dwnld_pics", "Download Pictures")
),
mainPanel(
DTOutput("tbl")
)
)
server <- function(input, output, session){
get_data <- reactive({
my_data %>%
filter(input$category == "All" |
ItemCategory == input$category) %>%
mutate(IconPath = map_chr(Icon, ~ as.character(img(src = .x,
height = "50px",
width = "50px"))))
})
output$tbl <- renderDataTable({
datatable(
get_data() %>%
select(Icon = IconPath, Category = ItemCategory,
"Sub Category" = SubCategory),
escape = FALSE
)
})
output$dwnld_data <- downloadHandler(
filename = function() {
paste0("data-", Sys.Date(), ".csv")
},
content = function(file) {
write.csv(get_data() %>%
select(Icon, Category = ItemCategory,
"Sub Category" = SubCategory), file,
row.names = FALSE)
}
)
output$dwnld_pics <- downloadHandler(
filename = function() {
paste0("pics-", Sys.Date(), ".zip")
},
content = function(file) {
fns <- get_data() %>%
pull(Icon)
zip(file,
file.path(here("Download", "www"), fns),
flags = "-r9Xj")
}
)
}
shinyApp(ui, server)
Explanation
All pics are in the www folder, from where shiny can add them to the page via the <img> tag.
In my my_data reactive, I filter the data according to the selections and add a string representation of the <img> tag, where I set height and width for the thumbnail sized pictures.
In renderDatatable I use escape = FALSE to not escape the HTML code and to render the picture.
Then the downloadHandler is rather straight forward, loop through all selected files and add them to a zip.
N.B. Theoretically you could also stay with your URI encoding strategy if you must. Your downloadHandler would become a bit more complicated in this case then however. You would first need to decode the encoded image string, store it to a temporary file and add this temporary file to the zip. Unless there are good reasons to go for this approach, I would not add this layer of complication.
Related
I'm trying to implement a shiny app that contains some optional checkboxes. I would like to know how do I perform an analysis with a certain selection only if it is selected and, with that, the table with the analysis made from the selection also appears on the screen.
I would like the objects inside the rbind function (below) to be included only if they are selected in the checkboxes:
ameacadas <- rbind(ameacadas_BR,ameacadas_BR2, ameacadas_pa)
External files can be found at: https://github.com/igorcobelo/data_examples (The 'minati.csv' file is the input data).
My code is presented below:
# global
library(shiny)
library(tidyverse)
# ui
ui <- navbarPage(title = "Minati Flora.",
tabPanel(title = "Home",
br(),
hr(),
# Upload csv file
sidebarLayout(
sidebarPanel(
fileInput(
inputId = "csvFile",
label = "Upload",
accept = c(".csv")
),
checkboxInput('BR1','Federal1'),
checkboxInput('BR2','Federal2'),
checkboxInput('PA','ParĂ¡'),
downloadButton("download", "Download")
),
mainPanel(
tableOutput("modifiedData")
)
)
),
tabPanel(title = "About"),
inverse = T)
# server
server <- function(input, output) {
rawData <- eventReactive(input$csvFile, {
req(input$csvFile)
df <- read.csv(input$csvFile$datapath,sep=';',check.names = F,fileEncoding = "Latin1")
#read extern files
ameacadas_BR <- read.csv("ameacadas_BR.csv",sep=';',check.names = F,fileEncoding = "Latin1")
legis_BR <- "Portaria MMA N. 148/2022"
ameacadas_BR2 <- read.csv("ameacadas_BR2.csv",sep=';',check.names = F,fileEncoding = "Latin1")
legis_BR2 <- "Decreto Federal N. 5.975/2006"
ameacadas_pa <- read.csv("ameacadas_PA.csv",sep=';',check.names = F,fileEncoding = "Latin1")
legis_pa <- "Resolucao COEMA/PA N. 54/2007"
#Rbind all files selected
ameacadas <- rbind(ameacadas_BR,ameacadas_BR2, ameacadas_pa)
#General calculate
colnames(df)[1] <- "Especie" #coluna especies
ameacadas <- ameacadas %>%
group_by(Especie) %>%
mutate(Categoria_Ameaca = toString(Categoria_Ameaca),
Legislacao = toString(Legislacao))
ameacadas <- ameacadas[!duplicated(ameacadas[,1]),]
arv_com_ameacadas <- df %>% left_join(ameacadas, by = "Especie")
})
output$modifiedData <- renderTable({rawData() })
output$download <- downloadHandler(
filename = function() {paste("Minati_Flora_", Sys.Date(), ".csv", sep = "")},
content = function(file){
write.csv(rawData(), file, row.names = FALSE)
}
)
}
# Run the application
shinyApp(ui = ui, server = server)
I am trying to build a shiny platform that can take in an input file, paste the output into a table on display, and then have a download button to download the results of the file back to your computer. I've tried numerous different ways, and it hasn't worked.
UI Code:
tabItem(tabName = "home",
h2("Cancer Publications Compiler"),
sidebarLayout(position = "left",
# File Upload
sidebarPanel(
radioButtons("data_t", "Select the Data Type Here",
c(Excel = ",", "Text = "\t")),
fileInput("data_f", "Upload Your Data Here")),
# Download Input
mainPanel(width = 8,align = "center",
div(style = "border:1px black solid;width:90%;font-size:10px;",tableOutput("out_chart")),
downloadButton("downloadData", "Download")))
),
Server:
fileext = reactive({
switch(input$data_t,
"Excel" = "csv", "Text" = "txt")
})
## Create Output for file selector ##
data_file <- reactive({
if(is.null(input$data_f)){return()}
else{
file_spec <- input$data_f
aa <- read.table(file_spec$datapath, header = TRUE, sep = input$data_t)
return(aa)
}
})
# Connects the input and output to launch the data table
## Create Output for table from tool ##
output$out_chart <- renderTable({
if(is.null(input$data_f)){return()}
else {
data_file()
}
})
output$donwloadData <- downloadHandler(
filename = function(){
paste("data-", fileext(), sep = ".")
},
content = function(file){
sep <- switch(input$data_t, "Excel" = ",", "Text" = "\t")
write.table(data_file(), file, sep = sep,
row.names = FALSE)
})
Can anyone help me with a fix for this problem so that the download handler will work how I want it to?
UPDATE: I have edited the code and have updated it on here. My problem now is that when I click download to download the outputted table, I am getting a .htm download of a very low rendered and weird looking version of my webpage.
You had some typos, and other issues. Try this
ui <- fluidPage(
tabItem(tabName = "home",
h2("Cancer Publications Compiler"),
sidebarLayout(position = "left",
# File Upload
sidebarPanel(
radioButtons("data_t", "Select the Data Type Here", c("Excel" = "csv", "Text" = "txt")) ,
fileInput("data_f", "Upload Your Data Here")
),
# Download Input
mainPanel(width = 8,align = "center",
div(style = "border:1px black solid;width:90%;font-size:10px;",tableOutput("out_chart")),
downloadButton("downloadData", "Download"))
)
)
)
server<- function (input, output, session) {
sep <- reactive({
req(input$data_t)
switch(input$data_t,
"csv" = ",", "txt" = "\t")
})
## Create Output for file selector ##
data_file <- reactive({
if(is.null(input$data_f)){return()}
else{
file_spec <- input$data_f
aa <- read.table(file_spec$datapath, header = TRUE, sep = sep())
return(aa)
}
})
# Connects the input and output to launch the data table
## Create Output for table from tool ##
output$out_chart <- renderTable({
print(input$data_t)
if(is.null(input$data_f)){return()}
else {
data_file()
}
})
output$downloadData <- downloadHandler(
filename = function(){
paste("data-", input$data_t, sep = ".")
},
content = function(file){
write.table(data_file(), file, sep = sep(), row.names = FALSE)
}
)
}
shinyApp(ui = ui, server = server)
I'm trying to get input from the User( a bunch of images) and then display them on R shiny using Lightbox gallery. Unfortunately I'm unable to get the images, Please help with this regard,Thank you in advance for your help .
below is my code:
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
fluidRow(
fileInput(inputId = "file_upload", label = "Upload Images", multiple = TRUE, accept = c('image/*', ".zip"),
width = NULL, buttonLabel = "Browse",
placeholder = "No file selected"),
actionButton("go","Run")
)
),
mainPanel(
fluidRow(
column(12,(uiOutput('lb'))
))
)
)
)
server <- function(input, output) {
vals<-reactiveValues(result=NULL,img_fldr_name=NULL,images=NULL)
observeEvent(input$file_upload, {
c_t <- Sys.time()
dt_str <- format(c_t, "%Y_%m_%d")
hr_str <- format(c_t, "%H_%M_%S")
vals$img_fldr_name <- paste0(dt_str, "_", hr_str)
if (tools::file_ext(input$file_upload$datapath)[[1]] %in% c("jpeg","png","jpg")){
create_folder_name=paste0("trials/www/",vals$img_fldr_name)
dir.create(path = create_folder_name)
for(i in 1:length(input$file_upload$datapath)){
file.copy(input$file_upload$datapath[[i]], paste0(create_folder_name,"/",input$file_upload$name[[i]]), overwrite = TRUE)
}
df <- list.files(paste0("trials/www/",vals$img_fldr_name), full.names = T)
print(df)
images<<-data.frame(src=list.files(paste0("trials/www/",vals$img_fldr_name), full.names = T))
#print(head(vals$images))
vals$result<-images
}
})
observeEvent(input$go,{
output$lb <- renderUI({
images <<- data.frame(src = vals$result$src)
vals$images <- images
lightbox_gallery <- function(df, gallery, display = 'block'){
print(df)
tags$div(style = sprintf('display: %s;', display),
tagList(tags$head(
tags$link(rel = "stylesheet", type = "text/css", href = "lightbox-2.10.0/lightbox.min.css"),
tags$link(rel = "stylesheet", type = "text/css", href = "gallerystyle.css")
),
tags$div(class = 'card-deck',
lapply(seq_len(nrow(df)), function(i){
print("Inside Loop")
print(df$src[i])
tags$div(`data-type`="template", class = 'card',
tags$a(#id = df$key[i],
href = df$src[i],
`data-lightbox` = gallery, # this identifies gallery group
`data-title` = paste0("Image"),
tags$span(style="color:black;text-align: center"),
tags$img(class = 'card-img-top',
src = df$src[i],
width = '80px',
height = 'auto')),
)
})
),
includeScript("www/lightbox-2.10.0/lightbox.min.js")
))
}
lightbox_gallery(vals$images, 'gallery', display = TRUE)
#paste0()
})
})
}
shinyApp(ui = ui, server = server)
Print statement inside loop gives proper path to image.
Also the respective folders and scripts are in place.
The code below works. I removed the nesting of how you prepare the output for better readability.
I think the main problem was that you read the image files from a directory outside www in your project folder. I would keep everything in there. This makes it easier. Take a look at the code: when the images are uploaded I explicitely save them to www/.... While preparing the output, I remove the www prefix using gsub, since Shiny is looking for resources in there by default.
Finally, make sure to use reactive values properly. You don't need to define a global images variable. Just use the reactive values. And there again, it is probably sufficient to have one reactive value which holds all the paths as a vector (e.g. paths <- reactiveVal(NULL)).
library(shiny)
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
fluidRow(
fileInput(inputId = "file_upload", label = "Upload Images", multiple = TRUE, accept = c('image/*', ".zip"),
width = NULL, buttonLabel = "Browse",
placeholder = "No file selected"),
actionButton("go","Run")
)
),
mainPanel(
fluidRow(
column(12,(htmlOutput('lb'))
))
)
)
)
server <- function(input, output) {
vals<-reactiveValues(result=NULL,img_fldr_name=NULL,images=NULL)
observeEvent(input$file_upload, {
c_t <- Sys.time()
dt_str <- format(c_t, "%Y_%m_%d")
hr_str <- format(c_t, "%H_%M_%S")
vals$img_fldr_name <- paste0(dt_str, "_", hr_str)
if (tools::file_ext(input$file_upload$datapath)[[1]] %in% c("jpeg","png","jpg")){
create_folder_name=paste0("www/trials/www/",vals$img_fldr_name)
dir.create(path = create_folder_name)
for(i in 1:length(input$file_upload$datapath)){
file.copy(input$file_upload$datapath[[i]], paste0(create_folder_name,"/",input$file_upload$name[[i]]), overwrite = TRUE)
}
images <- data.frame(src=list.files(paste0("www/trials/www/",vals$img_fldr_name), full.names = T))
vals$result <- images
}
})
get_lb <- eventReactive(input$go,{
images <- data.frame(src = vals$result$src)
vals$images <- images
lightbox_gallery(vals$images, 'gallery', display = TRUE)
})
lightbox_gallery <- function(df, gallery, display = 'block'){
tags$div(style = sprintf('display: %s;', display),
tagList(tags$head(
tags$link(rel = "stylesheet", type = "text/css", href = "lightbox.min.css"),
tags$link(rel = "stylesheet", type = "text/css", href = "gallerystyle.css")
),
tags$div(class = 'card-deck',
lapply(seq_len(nrow(df)), function(i){
print("Inside Loop")
print(df$src[i])
tags$div(`data-type`="template", class = 'card',
tags$a(#id = df$key[i],
href = gsub("^www/", "", df$src[i]),
`data-lightbox` = gallery, # this identifies gallery group
`data-title` = paste0("Image"),
tags$span(style="color:black;text-align: center"),
tags$img(class = 'card-img-top',
src = df$src[i],
width = '80px',
height = 'auto')),
)
})
),
includeScript("www/lightbox.min.js")
))
}
output$lb <- renderUI({
get_lb()
})
}
shinyApp(ui = ui, server = server)
I am working on an app where the user can upload either one file or multiple files of individual-level data to get analyzed.
So far if the user uploads multiple files the app combines all the files in one dataset and analyzes all of them combined. I have different outputs 2 tables and a graph.
What I am struggling to do is when the user uploads multiple files I want to keep the compiled result but I want to add dynamic tabs to each box according to the number of files uploaded to present the table/graph for that file alone.
I added a checkbox so the user checks it if they are uploading multiple files. The idea was to write an observeEvent code to insert tabs according to the number of files being uploaded, that code got complicated because I had to put the renderTable chunk within it, and it is not working.
So my question is, is there a better way of doing what I am trying to do? and If my idea makes sense what is wrong with my code and why isn't it working? Thank you
Here is a sample of the code;
library(shiny)
library(dplyr)
library(shinydashboard)
library(tidyr)
library(shinyjs)
ui <- dashboardPage(
dashboardHeader(title = "Treatment and Care Cascade",
titleWidth = 300),
#Sidebar contents (tabs)
dashboardSidebar(
sidebarMenu(
menuItem("HIV Cascade", tabName = "hiv")
)),
#Main panel for displaying outputs
dashboardBody(
tabItems(
#First tab content
tabItem(tabName = "hiv",
h2("HIV Treatment and Care Cascade"),
fluidRow(
#Input: Select a file for hcv data
box(fluidRow(
box(fileInput("dt_hiv","Choose CSV File",
multiple = TRUE,
accept = c("text/csv",
"text/comma-separated-values,tesxt/plain",".csv")),width = 12,solidHeader = TRUE, height = 75),
#Input: Checkbox if file has header
box(checkboxInput("multiplehiv", "Uploading multiple files",TRUE),width = 3,solidHeader = TRUE, height = 50)), width = 12, height = 255),
#Outputs
tabBox(id = "hivcasbox", tabPanel(id = "tab1", title ="HIV Cascade",tableOutput("hivcascade"))),
box(tableOutput("hivCascadeduration"), title = "HIV Cascade - duration", solidHeader = TRUE)
))
)))
server <- function(input, output){
#Combining the datasets together
dthiv <- reactive({req(input$dt_hiv)
rbindlist(lapply(input$dt_hiv$datapath, fread, header = input$hivheader, quote = input$hivquote, sep = input$hivsep),
use.names = TRUE, fill = TRUE)
})
#The analysis chunk
cascade_hiv <- reactive({dthiv() %>% summarize("Diagnosed" = sum(hiv_posresult,na.rm = T),
"Linkage to care" = sum(linkagetocare_hiv,na.rm = T))})
cascade_hiv1 <- reactive({as.data.frame(t(cascade_hiv()))})
Percentage <- reactive({(round((cascade_hiv1()$V1*100/cascade_hiv1()$V1[1]),1))})
cascade_hiv3 <- reactive({cbind(cascade_hiv1(),Percentage())})
cascade_hiv4 <- reactive({cascade_hiv3() %>% rename(Total = V1, Percentage = "Percentage()")})
output$hivcascade <- renderTable({
cascade_hiv5 <- as.data.frame(cascade_hiv4())
rownames(cascade_hiv5) <- c("Diagnosed","Linkage to care")
cascade_hiv5},include.rownames = TRUE)
observeEvent(input$multiplehiv, {
for (i in 1:length(input$dt_hiv$datapath)) {
insertTab(inputId = "hivcasbox",
tabPanel(paste("Region",i), renderTable({
dthiv_r <- input$dt_hiv$datapath[i] %>% summarize("Diagnosed" = sum(hiv_posresult,na.rm = T),
"Linkage to care" = sum(linkagetocare_hiv,na.rm = T))
cascade_hiv1_r <- as.data.frame(t(dthiv_r))
Percentage_r <- round((cascade_hiv1_r$V1*100/cascade_hiv1_r$V1[1]),1)
cascade_hiv3_r <- cbind(cascade_hiv1_r,Percentage_r)
cascade_hiv4_r <- cascade_hiv3_r %>% rename(Total = V1, Percentage = "Percentage_r")
cascade_hiv5_r <- as.data.frame(cascade_hiv4_r)
rownames(cascade_hiv5_r) <- c("Diagnosed","Linkage to care")
cascade_hiv5_r},include.rownames = FALSE)),
target = "tab1")
}
})
}
shinyApp(ui, server)
Created on 2019-08-01 by the reprex package (v0.3.0)
the app runs but when I check the multiple files box, no tabs get inserted
I couldn't get the above code to work but I found another one that works using "str and eval(parse(text = str))",
however, it is not the most elegant or concise code, so I would appreciate it if someone has a better way of doing it. Thank you!
ibrary(shiny)
library(dplyr)
library(shinydashboard)
library(tidyr)
library(shinyjs)
library(data.table)
ui <- dashboardPage(
dashboardHeader(title = "Treatment and Care Cascade",
titleWidth = 300),
dashboardSidebar(
sidebarMenu(
menuItem("HIV Cascade", tabName = "hiv")
)),
dashboardBody(
tabItems(
#First tab content
tabItem(tabName = "hiv",
h2("HIV Treatment and Care Cascade"),
fluidRow(
#Input: Select a file for hcv data
box(fluidRow(
box(fileInput("dt_hiv","Choose CSV File",
multiple = TRUE,
accept = c("text/csv",
"text/comma-separated-values,tesxt/plain", ".csv")),width = 12,solidHeader = TRUE, height = 75),
#actionButton("multiplehiv", "Add 'Dynamic' tab"),
#Input: Checkbox if file has header
box(checkboxInput("multiplehiv", "Uploading multiple files",FALSE),
width = 3,solidHeader = TRUE, height = 50)
), width = 12, height = 255),
#Outputs
uiOutput("tabs")
))
)))
server <- function(input, output){
dthiv <- reactive({req(input$dt_hiv)
rbindlist(lapply(input$dt_hiv$datapath, fread),
use.names = TRUE, fill = TRUE)
})
cascade_hiv <- reactive({dthiv() %>% summarize("Diagnosed" = sum(hiv_posresult,na.rm = T),
"Linkage to care" = sum(linkagetocare_hiv,na.rm = T))})
cascade_hiv1 <- reactive({as.data.frame(t(cascade_hiv()))})
Percentage <- reactive({(round((cascade_hiv1()$V1*100/cascade_hiv1()$V1[1]),1))})
cascade_hiv3 <- reactive({cbind(cascade_hiv1(),Percentage())})
cascade_hiv4 <- reactive({cascade_hiv3() %>% rename(Total = V1, Percentage = "Percentage()")})
n_files <- reactive({length(input$dt_hiv$datapath)})
output$tabs <- renderUI({
if (input$multiplehiv == 1) {
str <- "tabBox(id = 'hivcasbox',
tabPanel(id = 'taball', title = 'HIV Cascade' ,tableOutput('hivcascade')),"
for (i in 1:n_files()) {str <- paste0(str, "tabPanel(id = paste('tab', ",i,") , title = paste('Data', ",i,") , tableOutput('hivcascader_",i,"')),")}
str <- gsub(",$",")",str)
eval(parse(text = str))
}
else {
tabBox(id = "hivcasbox",
tabPanel(id = "tab1", title = "HIV Cascade",tableOutput("hivcascade")))
}
})
output$hivcascade <- renderTable({
cascade_hiv5 <- as.data.frame(cascade_hiv4())
rownames(cascade_hiv5) <- c("Diagnosed","Linkage to care")
cascade_hiv5},include.rownames = TRUE)
dt_files <- reactive({lapply(input$dt_hiv$datapath[1:n_files()],read.csv)})
observe({
for (i in 1:n_files())
{str1 <- paste0("dthiv_r_",i,"<- reactive({dt_files()[[",i,"]] %>% summarize('Diagnosed' = sum(hiv_posresult,na.rm = T),
'Linkage to care' = sum(linkagetocare_hiv,na.rm = T))})
cascade_hiv1_r_",i,"<- reactive({as.data.frame(t(dthiv_r_",i,"()))})
Percentage_r_",i,"<- reactive({round((cascade_hiv1_r_",i,"()$V1*100/cascade_hiv1_r_",i,"()$V1[1]),1)})
cascade_hiv3_r_",i," <- reactive({cbind(cascade_hiv1_r_",i,"(),Percentage_r_",i,"())})
cascade_hiv4_r_",i,"<- reactive({cascade_hiv3_r_",i,"() %>% rename(Total = V1, Percentage = 'Percentage_r_",i,"()')})")
eval(parse(text = str1))}
for (i in 1:n_files()) {
str2 <- paste0("output$hivcascader_",i," <- renderTable({
cascade_hiv5_r_",i," <- as.data.frame(cascade_hiv4_r_",i,"())
rownames(cascade_hiv5_r_",i,") <- c('Diagnosed','Linkage to care')
cascade_hiv5_r_",i,"},include.rownames = TRUE)")
eval(parse(text = str2))}
})
}
shinyApp(ui, server)
I'm trying to download my datatable into, a csv. file. Unfortuantely, even though the download starts, it's stuck with calculating and doesn't save the data. The file size is 8mb large and I only could workaround this issue with downloading only the filtered dataset. I also tried setting the donload size to 10 mb with shiny.maxRequestSize=30*1024^2
I really need the option to save the whole dataset. If anyone could provide some insights I would much appreciate it (And yes, I run the App in the Browser)
my ui function looks like this:
tbl <- read.csv(file.choose(new = FALSE), header = TRUE, sep = ",", row.names=1)
ui <- navbarPage(
title = "Data Table Options",
#Tab with the dataset table
tabPanel("Lot Dataset",
div(h3("Download"), style = "color:blue"),
helpText(" Select the download format"),
radioButtons("type", "Format type:",
choices = c("Excel (CSV)", "Text (Space Separated)", "Doc")),
helpText(" Click on the download button to download the Lot Dataset"),
downloadButton("download_filtered", "Download Filtered Data"),
br(),
br(),
br(),
DT::dataTableOutput("dt"), #datatable
),
)
my server function like this:
server <- function(session, input, output) {
#Increasing Downloadsize to 10MB
options(shiny.maxRequestSize=10*1024^2)
#render the datatable
output$dt <- DT::renderDataTable({
datatable(tbl, filter = "top", options = list(
lengthMenu = list(c(25, 50, 100, -1), c("25", "50", "100", "All")),
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) {
#write tbl with filter
write.csv(tbl[input[["dt_rows_all"]], ],
file = file, row.names = F)
}
)
}
Any help appreciated!!!