2016-05-04 6 views
1

Ich möchte die Tabelle und den Barplot, die von meiner glänzenden App generiert wurden, als PDF-Bericht herunterladen. Ich kann den Bericht mit den ausgewählten Eingaben erzeugen, wenn ich die App zum ersten Mal auf meinem lokalen Computer starte, aber wenn ich die Eingaben umschalte, erzeugt er nicht die Berichte der neuen Eingaben auf pdf.Wie man PDF-Download in glänzenden App-Antwort auf Benutzereingaben machen?

Hier ist mein ui Code

require(shiny) 
require(shinydashboard) 
require(ggplot2) 
require(ggthemes) 

sample <- read.csv("new_sample2.csv", stringsAsFactors = FALSE) 

header <- dashboardHeader(title = "XYZ School Student Dashboard", titleWidth = 370) 

body <- dashboardBody(
tags$head(tags$style(HTML(' 
    .main-header .logo { 
         font-family: "Georgia", Times, "Times New Roman", serif; 
         font-weight: bold; 
         font-size: 20px; 
         } 
         '))), 
fluidRow(
column(width = 9, 
box(title = "Selected Student", width = NULL, solidHeader = TRUE, status = "info", 
      textOutput("summary1"), 
      textOutput("summary2"), 
      textOutput("summary3") 
), 

     box(title = "Marks card", status = "info", width = NULL, solidHeader = TRUE, collapsible = TRUE, 
      tableOutput("table")), 
     box(title = "Marks card bar plot", status = "info", width = NULL, solidHeader = TRUE, collapsible = TRUE, 
      plotOutput("plot")) 
), 

column(width = 3, 
     box(title = "Select", background = "blue" ,width = NULL, 
      selectInput("class", "Class", unique(sample$class)), 
      selectInput("name", "Name", unique(sample$name)), 
      selectInput("exams", "Exams", choices = c("1st Periodic Test", "1st Term", "2nd Periodic Test", 
                "2nd Term", "3rd Periodic Test", "4th Periodic Test", 
                "Final")), 

      "Note: In the Bar Plot", 
      br(), 
      "1. The black line is the average class mark for that particular subject.", 
      br(), 
      "2. The red line is the pass mark for that particular subject.", 
      hr(), 
      downloadButton("downloadReport", "Download report") 
      ) 
     ) 
) 
) 


ui <- dashboardPage(skin = "blue", 
    header, 
     dashboardSidebar(disable = TRUE), 
     body 
) 

Und hier ist mein Server-Code

server <- function(input, output, session){ 

output$summary1 <- renderText({ 
paste("Student Name: ", input$name) 
}) 

output$summary2 <- renderText({ 
paste("Class: ", input$class) 
}) 
output$summary3 <- renderText({ 
paste("Examination: ", input$exams) 
}) 


getdataset <- reactive({ 
dataset <- sample[sample$class == input$class & sample$name == input$name & sample$examination == input$exams, ] 
}) 

observe({ 
classInput <- input$class 
updateSelectInput(session, "name", choices = sample$name[sample$class == classInput]) 
}) 

output$table <- renderTable({ 
dataset <- getdataset() 
dataset[, c("date", "subject", "maximum_mark", "pass_mark", "obtain_mark", "class_ave", "pc", "exam_pc")] 
}) 

plotInput <- reactive({ 
df <- getdataset() 
ggplot(df, aes(x = subject, y = obtain_mark)) + 
    theme_fivethirtyeight() + 
    geom_bar(stat = "identity", fill = "#006699") + 
    geom_text(aes(label = obtain_mark),vjust = -0.4) + 
    geom_errorbar(data = getdataset(), 
       aes(y = class_ave, ymax = class_ave, 
        ymin = class_ave), colour = "#000000") + 
    geom_errorbar(data = getdataset(), 
       aes(y = pass_mark, ymax = pass_mark, 
        ymin = pass_mark), colour = "red") + 
    labs(title = paste(input$name,"'s", input$exams, "marks"), x = "", y = "Marks") + 
    theme(axis.text=element_text(size=10, face = "bold") 
) 
}) 

output$plot <- renderPlot({ 
print(plotInput()) 
}) 

output$downloadReport <- downloadHandler(
filename = "Student-report.pdf", 
content = function(file){ 
    inputEnv <- new.env() 
    inputEnv$class <- input$class 
    inputEnv$name <- input$name 
    inputEnv$exams <- input$exams 
    inputEnv$data <- getdataset() 
    out = rmarkdown::render("student_report.Rmd", envir = inputEnv) 
    file.rename(out, file) 
    } 
    ) 
    } 

shinyApp(ui, server) 

Dies ist die .Rmd Datei, die ich im selben Ordner abgelegt haben, wo app.R ist.

Die Daten sind eine Stichprobe von Noten, die von Schülern in von der Schule durchgeführten Prüfungen erzielt wurden.

head(sample) 
class name  examination  date  subject maximum_mark pass_mark obtain_mark pc class_ave 
1 1 Adison 1st Periodic Test 2015-03-23  English-I  20   8   14  70  15 
2 1 Adison 1st Periodic Test 2015-03-24 Mathematics  20   8   19  95  16 
3 1 Adison 1st Periodic Test 2015-03-25  Science  20   8   18  90  12 
4 1 Adison 1st Periodic Test 2015-03-26   Hindi  20   8   20 100  15 
5 1 Adison 1st Periodic Test 2015-03-27 Social Studies  20   8   19  95  11 
6 1 Adison 1st Periodic Test 2015-03-28   M.M  20   8   20 100  14 
exam_pc 
1 92.86 
2 92.86 
3 92.86 
4 92.86 
5 92.86 
6 92.86 

tail(sample) 
    class name examination  date  subject maximum_mark pass_mark obtain_mark pc class_ave 
1851 2 Denver  Final 2015-12-10 English-II   100  40   93 93  59 
1852 2 Denver  Final 2015-12-02  Drawing   50  20   25 50  34 
1853 2 Denver  Final 2015-11-30   GK   50  20   50 100  42 
1854 2 Denver  Final 2015-12-01 Moral Science   50  20   50 100  41 
1855 2 Denver  Final 2015-12-02  Dictation   25  10   25 100  20 
1856 2 Denver  Final 2015-11-30 Hand Writing   25  10   25 100  20 
     exam_pc 
1851 87.89 
1852 87.89 
1853 87.89 
1854 87.89 
1855 87.89 
1856 87.89 

Ich würde wirklich Ihre Hilfe zu schätzen wissen.

+0

Ich würde vorschlagen, dass Sie eine parametrisierte r Abschlags Skript schreiben, um den Bericht zu erstellen. Sie können den Build und Download starten, indem Sie 'rmarkdown :: render 'in' downloadHandler' aufrufen. – Benjamin

+0

Hallo, könnten Sie etwas mehr dazu ausführen, wie ich ein parametrisiertes r Markdown-Skript schreibe. Was ich bisher getan habe, um dies zu erreichen, besteht darin, ähnliche Fragen zu Stackoverflow- und Google-Gruppen zu lesen und den Code hier zu implementieren. – Loy

Antwort

3

Ich entschuldige mich, dass es so lange gedauert hat, um darauf zurückzukommen. Nachdem ich gesehen habe, was ich getan habe, stellte sich heraus, dass es etwas mehr involviert war, als ich es in Erinnerung hatte.

Hier ist mein Beispiel App-Code

library(shiny) 
library(ggplot2) 
library(magrittr) 

ui <- shinyUI(
    fluidPage(
    column(
     width = 2, 
     selectInput(
     inputId = "x_var", 
     label = "Select the X-variable", 
     choices = names(mtcars) 
    ), 
     selectInput(
     inputId = "y_var", 
     label = "Select the Y-variable", 
     choices = names(mtcars) 
    ), 
     selectInput(
     inputId = "plot_type", 
     label = "Select the plot type", 
     choices = c("scatter plot", "boxplot") 
    ), 
     downloadButton(
     outputId = "downloader", 
     label = "Download PDF" 
    ) 
    ), 
    column(
     width = 3, 
     tableOutput("table") 
    ), 
    column(
     width = 7, 
     plotOutput("plot") 
    ) 
) 
) 

server <- shinyServer(function(input, output, session){ 

    #**************************************** 
    #* Reactive Values 

    table <- reactive({ 
    mtcars[, c(input[["x_var"]], input[["y_var"]])] 
    }) 

    plot <- reactive({ 
    p <- ggplot(data = mtcars, 
       mapping = aes_string(x = input[["x_var"]], 
            y = input[["y_var"]])) 
    if (input[["plot_type"]] == "scatter plot") 
    { 
     p + geom_point() 
    } 
    else 
    { 
     p + geom_boxplot() 
    } 
    }) 

    #**************************************** 
    #* Output Components 

    output$table <- 
    renderTable({ 
     table() 
    }) 

    output$plot <- 
    renderPlot({ 
     plot() 
    }) 

    #**************************************** 
    #* Download Handlers 

    output$downloader <- 
    downloadHandler(
     "results_from_shiny.pdf", 
     content = 
     function(file) 
     { 
      rmarkdown::render(
      input = "report_file.Rmd", 
      output_file = "built_report.pdf", 
      params = list(table = table(), 
          plot = plot()) 
     ) 
      readBin(con = "built_report.pdf", 
        what = "raw", 
        n = file.info("built_report.pdf")[, "size"]) %>% 
      writeBin(con = file) 
     } 
    ) 
}) 

shinyApp(ui, server) 

Und hier ist mein RMD (mit dem Titel report_file.Rmd)

--- 
title: "Parameterized Report for Shiny" 
output: pdf_document 
params: 
    table: 'NULL' 
    plot: 'NULL' 
--- 

```{r} 
params[["plot"]] 
``` 

```{r} 
params[["table"]] 
``` 

Einige Highlights für

  • Hinweis aussehen besteht aus params in der YAML Vorderseite des RMarkdown-Skripts. Dadurch können wir beim Aufruf eine Liste von Werten übergeben, die im Skript verwendet werden. rmarkdown::render(..., params = list(...))
  • Ich baue meine PDF immer in eine Dummy-Datei. So ist es einfach zu finden.
  • Der Grund, warum ich immer zu einer Dummy-Datei baue, ist, dass, um den Download-Handler zum Laufen zu bringen, müssen Sie den Bit-Inhalt der PDF lesen und drücken Sie file Argument mit writeBin. Siehe meine downloadHandler Konstruktion.
  • Die Verwendung des parametrierten Berichts bedeutet, dass Sie Ihre Ausgaben im Skript rmarkdown nicht neu erstellen müssen. Die Arbeit wurde in der Shiny-App erledigt, der parametrisierte Bericht hilft Ihnen einfach, die Objekte korrekt zu senden. Es ist nicht das gleiche wie das Weiterleiten von Dateien hin und her (obwohl, wenn es so einfach sein könnte, würde ich es gerne wissen).

mehr über parametrisiert Berichte Lesen Sie hier: http://rmarkdown.rstudio.com/developer_parameterized_reports.html

+0

Es funktioniert ordnungsgemäß. Danke für das Beispiel und den Link zu parametrisierten Berichten. Ich habe viel gelernt. – Loy