The code below produces a DataTable output that I'd like to have it emailed using an Email button, similar to the Export button created below. Is there an easy way to add a button so that when you click, it pops up Microsoft Outlook to send the datatable as an attachment, say in csv format?
Also, please click here and here to help with a similar questions.
#Load required packages
require(shiny)
#Create a dataframe
df <- data.frame(random=1:160)
server <- function(input,output,session){
#Display df using DataTable and apply desired options
output$display <- renderDataTable({df},
option=list(pageLength=100,
"dom" = 'T<"clear">lfrtip',
"tableTools" = list(
"sSwfPath" = "//cdn.datatables.net/tabletools/2.2.3/swf/copy_csv_xls_pdf.swf",
"aButtons" = list(list("sExtends" = "csv","oSelectorOpts"=list("page"="all"),"sButtonText" = "Export","aButtons" ="csv")))
)
)
}
ui <- shinyUI(fluidPage(
#Add a title
h1('Testing TableTools'),
#Add required JS libraries
tagList(
singleton(tags$head(tags$script(src='//cdn.datatables.net/1.10.4/js/jquery.dataTables.min.js',type='text/javascript'))),
singleton(tags$head(tags$script(src='//cdn.datatables.net/tabletools/2.2.3/js/dataTables.tableTools.min.js',type='text/javascript'))),
singleton(tags$head(tags$link(href='//cdn.datatables.net/tabletools/2.2.3/css/dataTables.tableTools.css',rel='stylesheet',type='text/css')))
),
mainPanel(
#Display results
dataTableOutput('display')
)
))
shinyApp(ui = ui, server = server)
A quick way is to use mailto(which works well with Outlook).
The mailto would need to be inside an HTML() tag for shiny to render it.
HTML(
<a href="mailto:hello#rshiny.com?
body='Hello,World! Check out my data.'
&subject='Data'
&attachment='\\myfolder\shinyData.csv'">click here for email!</a>
)
There are two hypothetical ways to do this.
Have the mailto in ui.R
The code would need to download the datatable at the user's end (probably in the temp folder), and attach it there.
Have the mailto in server.R
You'll need the csv file already saved on your server in order to load it as an attachment. You would need to use the above code inside a renderUI() and also pass the file from your server to the user's end.
There is a downloadHandler() function which allows users to download from the server which could be of use for the above.
I've never tried passing attachments around as you are trying, however the above logic should both allow you to create an email, and get you on the right path to attaching files.
Related
I need to save the edits performed in Shiny by the user on a table that is rendered using the renderDataTable back to the original table.
I'm using the DT package to render a table used in the server instance. The table is meant to be viewed, filtered, and edited by the user. Then, more importantly, to be saved back to the server for further processing.
DataTableOuput ui instance provides the ability to edit records in the rendered table, and it allows to save a csv copy with the edited version (using the extensions and buttons property), but I cannot find a way to save the edited table back to the server instead of saving it to external file.
Below is a sample reproducible code using mtcars table of what I've done. I appreciate any assistance to modify the code or even to suggest other packages that can accomplish the task.
library(shiny)
library(DT)
if (interactive()) {
tbl1 <- mtcars
ui <- fluidPage(
DT::dataTableOutput("MasterData")
)
server <- function(input, output, session) {
output$MasterData <- DT::renderDataTable({
DT::datatable(tbl1,
extensions = "Buttons",
rownames=FALSE,
editable = TRUE,
filter="top",
style = "bootstrap",
options = list(
autoWidth=TRUE,
dom='Blfrtip',
buttons=c('copy','csv','excel'),
lengthMenu=c(50,100,500,1000)
)
)
})
}
shinyApp(ui, server)
}
Sorry for what seems like a basic question, I'm very new to R and programming in general. I want to be able to determine what file type was picked from a file. For example, in this code I need to have two separate buttons for importing a CSV or excel file:
observeEvent(input$CSV, {
Table <- read.table(file.choose(), header=TRUE, sep=",")
output$ImportedTable <- DT::renderDataTable(Table)
})
observeEvent(input$Excel, {
Table <- read_excel(file.choose())
output$ImportedTable <- DT::renderDataTable(Table)
})
(input$Excel/CSV is the output of an actionButton in the main pannel)
Ideally, I'd like to only require one button instead of two, and have the program able to determine what file type was chosen, and import it accordingly. and ideally, I'd like to be able to sort what data types are available to choose from when importing, since currently it allows the user to pick all file types, instead of just ones in a table format. I'd appreciate any help, thanks!
You seem to work with shiny (this is an important bit of information missing from your main post).
In shiny you can use fileInput to restrict the format of input files. Here is a minimal reproducible example.
library(shiny)
ui <- fluidPage(
fileInput(inputId = "file_csv", label = "CSV file", accept = ".csv"),
fileInput(inputId = "file_xlsx", label = "XLSX file", accept = ".xlsx"),
)
server <- function(input, output) {
}
shinyApp(ui = ui, server = server)
Note that you can see the effect of accept when opening the app in your browser of choice. RStudio's native app window or Viewer Pane does not seem to respect the accept argument.
In my Shiny app, I run calculations, generate a data frame, and want the user to be able to save (download) it.
My relevant code in ui.R:
textInput("downFile","Save the File:", value = "Results File"),
downloadButton('downFile',"Save File"),
My relevant code in server.R:
output$downFile <- downloadHandler(
filename = function() {
paste0(input$downFile, " ", Sys.Date(), ".csv")
},
content = function(file) {
write.csv(MyMainFunction()$mydataframe, file, row.names = FALSE)
}
)
Everything works. But I have two issues:
If by mistake the user clicks on "Save File" before all the calculations in server.R have been completed, he gets an error ("Failed - Network Error").
After all the calculations, when the user clicks on the "Save File" button, the file is immediately saved in "Downloads" folder.
Two questions:
Is it possible to make the button invisible until the calculations in my main function (MainFunction) are completed?
How could I allow the user to select a desired folder to download the results to? (as in "Save in...")
Thank you very much!
for question 1: Use shinyjs package learn more in https://deanattali.com/shinyjs/
library(shinyjs)
disable("downFile") # or use hide() Before all calculations
enable("downFile") # or use show() After
For question 2: I think this is more about setting up your browser than the shiny
If you are using chrome go to the advanced settings and enable
I would like to be able to use display.mode = 'showcase' in an app run with the shinyApp() function call. According to the docs I should be able to pass any arguments that go runApp() through the options argument. The showcase mode works (the window is split) but it does not show the code. What's interesting is that if I run runExample("01_hello") everything works fine. I'm using shiny 1.0.5.
Code:
library(shiny)
ui <- fluidPage(
titlePanel("Sample App"),
sidebarLayout(
sidebarPanel(
selectInput("data", label = "Data set",
choices = c("mtcars", "iris"))
),
mainPanel(
tableOutput("table")
)
)
)
server <- function(input, output) {
data <- reactive({
get(input$data, 'package:datasets')
})
output$table <- renderTable({
head(data())
})
}
shinyApp(ui, server, options = list(display.mode = 'showcase'))
Output:
I was having the same issue. I had the app.R file and created the DESCRIPTION file using notepad but couldn't deploy a shinyApp with the code. Then I copied the DESCRIPTION file from shiny\examples\01_hello and noticed this:
Turns out my file had a TXT extension, so Shiny wasn't reading it as a metadata file. Once I used the correct DESCRIPTION file (which you can edit using notepad), everything worked out fine.
This is more of an addendum to Gus_est's answer, since I had the same problem and wasn't able to get it run right from there.
Create a file inside the directory your app.R-file resides in, e.g. a txt-file. Write into the file what display mode is to be used using Debian Control file format. In our case it would look like that (Title is not necessary):
Title: My App
DisplayMode: Showcase
Then rename the file DESCRIPTION without providing a file ending. Ignore the warning.
When you run the app now, it will always be in display mode "showcase", you can override this only inside the runApp()-statement. So I find the documentation to be misleading.
Check your current working directory. This problem seems to occur, if the working directory is not set to the folder with the app code.
I am new to Shiny and I have created a really simple shiny app:
library(shiny)
ui <- fluidPage(
fluidRow(column(7,dataTableOutput('dto')))
)
server <- function(input,output){
output$dto <- renderDataTable({MYTABLE})
}
runApp(list(ui=ui,server=server))
Is there any way to put an option to download the result of the table (doesn't matter if is CSV, XLSX...)
cheers
That's pretty easy with downloadButton() or downloadLink() in combination with downloadHandler if you make the data itself a reactive expression. Then you can download whatever you send to output using the same reactive expression.
A small example:
library(shiny)
ui <- fluidPage(
# This one is linked by the id 'download'
downloadButton('download',"Download the data"),
fluidRow(column(7,dataTableOutput('dto')))
)
server <- function(input,output){
# Reactive expression with the data, in this case iris
thedata <- reactive(iris)
output$dto <- renderDataTable({thedata()})
output$download <- downloadHandler(
filename = function(){"thename.csv"},
content = function(fname){
write.csv(thedata(), fname)
}
)
}
runApp(list(ui=ui,server=server))
Keep in mind:
the argument content of downloadHandler must be a function producing a file! It should take one argument for the connection/file name. In this example it is a csv file, but for eg images you can use png() and dev.off(), for ggplots you can use ggsave(), ...
the argument filename does not have to be a function, but I found it works
better that way. Especially when working with reactive expressions for the file name.
you link the downloadHandler and the downloadButton through the output list: the id of downloadButton is the name of the output element returned by downloadHandler.
EDIT:
Some people try to use download.file() for this, but that's wrong as well. The function download.file() works when used on the user side, not the server side. It lets you download files from the internet to the computer that is calling the function. If you'd use that in a Shiny application, it would work when run locally. That's because user and server are the same machine. However, when deploying your app on a Shiny Server, download.file() would essentially be downloading files TO the server, not from.
A slightly alternative solution based directly on the datatable / DT extension buttons.
I am shamelessly borrowing the example data from Joris...
library(shiny)
library(DT)
ui <- fluidPage(
# This one is linked by the id 'download'
fluidRow(column(7,dataTableOutput('dto')))
)
server <- function(input,output){
# Reactive expression with the data, in this case iris
thedata <- reactive(iris)
#the extensions parameter coupled with the options list does the trick
output$dto <- renderDataTable(thedata(), extensions = 'Buttons',
options = list(dom = 'Bfrtip',
buttons = c('copy', 'csv', 'excel', 'pdf', 'print'))
)
}
runApp(list(ui=ui,server=server), launch.browser=TRUE) #now runs by default in the external browser.
This will work with different outputs and personally I like the cleaner look. Just make sure that you are running the demo in the external browser. Otherwise it won't work.
I have to execute the app in the browser because the filename isn't working. I use
runApp(list(ui=ui,server=server),launch.browser = T)
and it works perfectly for me.
If you don't want to use launch.browser=TRUE you can write the filename and the extension for example .csv at the end of the filename when you use the download button in the shiny app.