RShiny: Input multiple image files and put them into a table - r

I'm trying to work on a project in shiny to compare images uploaded by user and that saved in my amazon s3 server.
while downloading from s3, I am using this:
save_object(object=xyz ,bucket = "xyz", file = paste0("www/",xyz,".jpg"))
I'm taking input as:
fileInput("image","upload the image")
My dataframe is like this:
a$name<- xyz
a$server_image<- paste0("<img src=",'"',"xyz.jpg",'"'," ","height=",'"',"300",'"',"></img>")
a$uploaded_image<- paste0("<img src=",'"',input$image$datapath,'"'," ","height=",'"',"300",'"',"></img>")
I'm trying to get output like below.
output$output_table<-DT::renderDataTable({DT::datatable(a,escape = FALSE)})
In this case, the image downloaded from aws s3 into "www/" directory is correctly showed in the table, but there is problem with viewing uploaded image.
I also tried to use file.copy on input$image to copy it to a folder "www", but it also doesn't work when I deploy the app.
How can I view an image taken using fileInput and View without using renderImage?

I'm suspecting that your app renders <img src=... before the file is copied in www.
A solution is to convert the image in its base64 encoding and then to render the table including the image from its base64 string.
library(shiny)
library(DT)
ui <- shinyUI(
fluidPage(
fileInput("image", "upload image"),
DT::dataTableOutput("table")
)
)
server <- shinyServer(function(input, output) {
base64 <- eventReactive(input$image, {
base64enc::dataURI(file=input$image$datapath, mime=input$image$type)
})
output$table <- DT::renderDataTable({
req(input$image)
dat <- data.frame(image = sprintf('<img src=%s height="300"></img>', base64()))
datatable(dat, escape=FALSE)
})
})

Related

Render image in UI created by r shiny

I am using R to generate an image (png file). How do I use shiny to render it to the ui?
source("#rasterBasePlot.R")
output$spatialMap <- renderImage ({
filename <- PNGFileName
# Return a list containing the filename
list(src = filename)
}, deleteFile = TRUE)
You can simply create a www folder inside your app folder and put the images you want to display there. After that something like the following should be sufficent:
library(shiny)
ui <- fluidPage(
tags$img(
src = "/myimage.png", width = 100
)
)
server <- function(input, output, session) {}
shinyApp(ui, server)
If you want to use folders other than www you can use addResourcePath to add resources to Shiny's web server. Please see this.

How to integrate code into a shiny app and upload files?

I'm new to shiny and I would like your advice on a requirement that I have at my office. I apologize in advance for not providing more information or code at the moment.
I have currently coded a R script that does the following:
Import 7 excel files with read_excel:
File 1 will go to dataset 1
File 2 will go to dataset 2
File 3,4,5,6,7 will go to dataset 3 by using lapply
Does a whole lot of data cleaning, formatting, parsing and ordering
Merges everything together and creates a final excel and txt files with specific formatting
Im requiring a shiny web app that:
Provides 3 different upload boxes for the user. One for each type of file (1 / 2 / 3,4,5,6,7)
Internally saves the uploaded files so the code i already have can use them for its processing
Lets the user download the 2 output files made by my code to the computer
If possible, show a log window on the app so the user can know if something goes wrong with the code execution
Datasets visualization is not required
I might be asking a lot. I will appreciate if you just can give me some lights in how i can start working on this. I would like not to modify my current code, if possible (can i have shiny acquire the files, and call my code so it can process them?)
Here is a minimal example showing uploading files, processing them, and downloading them.
For simplicity I've used 3 inputs and a single output.
If you want to notify a user that something has happened, you can use showNotification()
library(shiny)
ui <- fluidPage(
#File Upload Boxes
fileInput("myfileinput_1", label = "Upload File 1", accept = ".csv"),
fileInput("myfileinput_2", label = "Upload File 2", accept = ".csv"),
fileInput("myfileinput_3", label = "Upload File 3", accept = ".csv"),
#Button
actionButton("mybutton", label = "Process Uploaded Files"),
#Table Showing Processed Data
tableOutput("mytable"),
#Download Buttons
downloadButton("myfiledownload", label = "Download Processed File")
)
server <- function(input, output, session) {
#A reactive dataframe to store our outputfile
reactives <- reactiveValues(
df_output = NULL
)
#Runs when button is pressed
observeEvent(input$mybutton, {
#Check that all 3 files are selected before loading
if(!is.null(input$myfileinput_1) & !is.null(input$myfileinput_2) & !is.null(input$myfileinput_3)) {
#Load input files
df_input_1 <- read.csv(input$myfileinput_1$datapath)
df_input_2 <- read.csv(input$myfileinput_2$datapath)
df_input_3 <- read.csv(input$myfileinput_3$datapath)
#Use input to create an output (we're just using a simple example)
reactives$df_output <- data.frame(
input = c("Input 1", "Input 2", "Input 3"),
rows = c(nrow(df_input_1), nrow(df_input_2), nrow(df_input_3))
)
showNotification("Files Successfully Processed", type = "message")
} else {
showNotification("Ensure all three files are selected before loading", type = "error")
}
})
#Table Output
output$mytable <- renderTable({
reactives$df_output
})
#Download handler
output$myfiledownload <- downloadHandler(
filename = "mydata.csv",
content = function(file) {write.csv(reactives$df_output, file, row.names = FALSE)}
)
}
shinyApp(ui, server)

Excel data distribution with Shiny

I am not good at English, so sentences may be wrong.
I want to distribute excel files prepared in advance to users. Is it possible to realize such a system with shiny? No problem with .zip.
Thank you
ui.R
shinyUI(
fluidPage(
downloadButton('downloadData', 'Excel Download')
)
)
server.R
shinyServer(function(input, output) {
output$downloadData <- downloadHandler(
filename = "distribution.xlsx",
content = "distribution_excel"
)
})
Yes, it is possible and you were nearly there. Below is a minimal working example. I assume that your .xlsx file is located in the same folder as your app.R. Notice that I have created the app in a single R file as opposed to two separate files.
The trick to getting the file to download is to use a function for the content inside of downloadHandler(). Specifically we are using the base function file.copy(). Clicking the button should now download the file: distribution.xlsx. This file can obviously be exchanged with a zip file.
If you want different users to access different Excel files, you can write an additional function inside of your server function that passes the file argument to the downloadHandler().
# Load packages ----
pkgs <- c("shiny")
invisible(lapply(pkgs, require, character.only = TRUE))
# Set up the UI ----
ui <- fluidPage(
# Define your download button
downloadButton(
outputId = "downloadData",
label = "Excel Download"
)
)
# Set up the server side ----
server <- function(input, output, session) {
# Define the download handler with function() for content.
output$downloadData <- downloadHandler(
filename = "distribution.xlsx",
content = function(file) {
file.copy("distribution.xlsx", file)
}
)
}
# Combine into an app ----
shinyApp(ui = ui, server = server)

link to local server files in a DT in RMarkdown [duplicate]

I want to include a link to a local html file, which lives inside the www directory of my shiny app, inside a column in data.table. On click a new tab should open showing the html file.
I've found solutions for linking to internet pages, but how do I adjust this, so that Shiny finds the local files, when rendered in a browser?
This is my code
library(DT)
library(shiny)
link <- "www/my_html.html"
link <- paste0("<a href='", link,"' target='_blank'>", link,"</a>") # works fine for global url, but not for local file
df <- data.frame(a = 10.5, b = 48, link = link)
ui <- fluidPage(
DT::dataTableOutput('table1')
)
server <- function(input, output) {
output$table1 <- DT::renderDataTable({df}, escape = -3)
}
shinyApp(ui, server)
Maybe you could try running your app using a shiny folder. Make sure your my_html.html file is located in a www folder in your shiny folder.
ui.R
library(DT)
library(shiny)
fluidPage(
DT::dataTableOutput('table1')
)
server.R
library(DT)
library(shiny)
df <- data.frame(a = 10.5, b = 48, link = "<a href='my_html.html' target='blank' >MyFile</a>")
function(input, output) {
output$table1 <- DT::renderDataTable({df}, escape = FALSE)
}
I think the main problem with your code is that you are specifying the address of your html file as link <- "www/my_html.html". You should drop out the www/.
It is true that inside your app directory you must have a www directory, and your html files should be inside this www directory. But to properly address your files you should think as if your working directory was already inside the www/ directory.
If you have your shinny app in a single app.R file or a combination of ui.R + server.R doesn't matter, both ways work.
The other detail is in the escape parameter of the renderDataTable() function. It should not be equal to -3, use instead: DT::renderDataTable({df}, escape = FALSE)
So the final code would look like this (supposing you have two html files):
library(shiny)
link <- c("my_html_1.html", "my_html_2.html")
link <- sprintf('click_here', link)
df <- data.frame(name = c("1st_file", "2nd_file"),
value = c(10.5, 48),
link = link)
ui <- fluidPage(
dataTableOutput('table1')
)
server <- function(input, output) {
output$table1 <- renderDataTable({df}, escape = FALSE)
}
shinyApp(ui, server)

R Shiny how to display a pdf file generated in "downloadHandler"

I am new to shiny and was wondering if there is a way to display a pdf file generated in "downloadHandler"?
I am using a package to do some biological analysis, and I can make it create a pdf file in downloadHandler. However, I am still struggling if I can view this pdf instead of downloading it.
This question is related to Shiny to output a function that generates a pdf file itself.
Please see the below for the code that works for downloading the pdf output. Thanks so much!
library(shiny)
library(msa)
runApp(list(
#Load the exmaple from the msa package.
mySequenceFile <- system.file("examples", "exampleAA.fasta", package="msa"),
mySequences <- readAAStringSet(mySequenceFile),
myFirstAlignment <- msa(mySequences),
# A simple shiny app.
# Is it possible to see the generated pdf file on screen?
ui = fluidPage(downloadButton('downloadPDF')),
server = function(input, output) {
output$downloadPDF = downloadHandler(
filename = 'myreport.pdf',
content = function(file) {
msaPrettyPrint(
myFirstAlignment
, file = 'myreport.pdf'
, output="pdf"
, showNames="left"
, showLogo="top"
, consensusColor="BlueRed"
, logoColors="accessible area"
, askForOverwrite=FALSE)
file.rename("myreport.pdf", file) # move pdf to file for downloading
},
contentType = 'application/pdf'
)
}
))
If you intend to display the pdf, you should not use downloadHandler. Instead, just use your pdf printing function to generate the pdf file, but the key is
Create a www folder under your Shiny project root
Point the file argument of msaPrettyPrint to www/myreport.pdf
Dynamically add an iframe to display the file. Note in the iframe you point to myreport.pdf directly without www, as Shiny automatically looks for static/media files inside the www folder.
See below for a working example (note I am not using the msa package here but the idea should be the same).
library(shiny)
ui <- shinyUI(fluidPage(
titlePanel("Old Faithful Geyser Data"),
sidebarLayout(
sidebarPanel(
actionButton("generate", "Generate PDF")
),
mainPanel(
uiOutput("pdfview")
)
)
))
server <- shinyServer(function(input, output) {
observeEvent(input$generate, {
output$pdfview <- renderUI({
pdf("www/myreport.pdf")
hist(rnorm(100))
dev.off()
tags$iframe(style="height:600px; width:100%", src="myreport.pdf")
})
})
})
shinyApp(ui = ui, server = server)

Resources