36

I am trying to create a shiny application that will allow you to download a nicely formatted PDF report, according to user-defined sub-analyses. I found this gist containing a minimal example, which works just fine. However, when I tried to add a plot, based on the 'Miles-per-gallon' example from the Rstudio gallery, I ran into some errors when I tried adapting the code.

Here is my server.R code:

library(knitr)
library(datasets)
library(ggplot2)

mpgData <- mtcars
mpgData$am <- factor(mpgData$am, labels = c("Automatic", "Manual"))

shinyServer(function(input, output) {
formulaText <- reactive({
    paste("mpg ~", input$variable)
})

# Return the formula text for printing as a caption
output$caption <- renderText({
    formulaText()
})

# Generate a plot of the requested variable against mpg and only 
# include outliers if requested
output$mpgPlot <- renderPlot({
    boxplot(as.formula(formulaText()), 
            data = mpgData,
            outline = input$outliers)
})

myPlot1 <- reactive({
    p <- print(ggplot(mpgData, aes(mpg, input$variable)) +
    geom_line())
})

 myPlot2 <- reactive({
     #renderPlot({
     p <- print(
         boxplot(as.formula(formulaText()), 
                 data = mpgData,
                 outline = input$outliers)
     )
 })

output$report = downloadHandler(
    filename = 'myreport.pdf',
    content = function(file) {
        out = knit2pdf('input.Rnw', clean = TRUE)
        file.rename(out, file) # move pdf to file for downloading
    },
    contentType = 'application/pdf'
)
})

and here is my ui.r code

library(shiny)
library(datasets)

shinyUI(fluidPage(

# Application title
titlePanel("Miles Per Gallon"),

# Sidebar with controls to select the variable to plot against mpg
# and to specify whether outliers should be included
sidebarLayout(
    sidebarPanel(
        textInput('firstname', 'First name', value = 'Adam'),
        textInput('lastname', 'Last name', value = 'Smith'),
        downloadButton('report'),

        selectInput("variable", "Variable:",
                    c("Cylinders" = "cyl",
                      "Transmission" = "am",
                      "Gears" = "gear")),

        checkboxInput("outliers", "Show outliers", FALSE)
    ),

    # Show the caption and plot of the requested variable against mpg
    mainPanel(
        h3(textOutput("caption")),

        plotOutput("mpgPlot")

    )
)
))

while the input.Rnw file looks like this:

\documentclass{article}

\begin{document}

<<names>>=
input$firstname
input$lastname
@

<<>>=
#output$mpgPlot ## N.B. This threw an error! Cannot call an object like this from shiny
print(myPlot1())
@

<<>>=
print(myPlot2())
@

\end{document}

I've been playing around with this for a few hours now, and I'm pretty stuck. The input$names part works fine, but I cannot figure out how to bring in a reactive plot. The error/warning message is 'Error: object ’input’ not found', so I know it is not detecting the input$variable changes being passed from the ui.R script. Thanks for your help solving this

sessionInfo()
R version 3.1.0 (2014-04-10)
Platform: x86_64-apple-darwin13.1.0 (64-bit)

locale:
[1] en_GB.UTF-8/en_GB.UTF-8/en_GB.UTF-8/C/en_GB.UTF-8/en_GB.UTF-8

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] ggplot2_0.9.3.1.99 knitr_1.6          shiny_0.10.0      

loaded via a namespace (and not attached):
 [1] bitops_1.0-6       caTools_1.17       colorspace_1.2-4   digest_0.6.4       evaluate_0.5.5     formatR_0.10       grid_3.1.0         gtable_0.1.2      
 [9] highr_0.3          htmltools_0.2.4    httpuv_1.3.0       labeling_0.2       MASS_7.3-33        munsell_0.4.2      plyr_1.8.1         proto_0.3-10      
[17] RColorBrewer_1.0-5 Rcpp_0.11.2        reshape2_1.4       RJSONIO_1.2-0.2    scales_0.2.4       stringr_0.6.2      tools_3.1.0        xtable_1.7-3
Yihui Xie
  • 28,913
  • 23
  • 193
  • 419
Jonny
  • 2,703
  • 2
  • 27
  • 35
  • 7
    That is interesting. Can you replace ggplot2 graphics with base graphics and see if it works? e.g. `plot(as.formula(formulaText()), data = mpgData)` – Yihui Xie Jul 22 '14 at 04:02
  • 1
    @Yihui Thank you, your suggestion worked, by replacing `print(myplot1())` with `plot(as.formula(formulaText()), data = mpgData)` in `input.Rnw`. I have tried adapting this to ggplot2, by adding `ggPlotText <- reactive({paste('mpg,', input$variable)})` to `server.R` and then `ggplot(mpgData, aes(ggPlotText())) + geom_line()` to `input.Rnw`, which seems to follow the logic of `formulaText()`, but the error message produced says `Error: could not find function "ggPlotText"`. Is there an equivalent to `as.formula()` that I can use for the `aes(x, y)` convention of ggplot2? `toString` didn't work – Jonny Jul 22 '14 at 10:59
  • 3
    It sounds like a ggplot2 variable scope problem. However, before you report this issue to ggplot2 authors, please make sure you have the latest version of ggplot2 (do `update.packages()`). – Yihui Xie Jul 23 '14 at 05:35
  • 2
    Have you tried ggplot with aes_string() ? Here is the documentation: http://docs.ggplot2.org/0.9.3/aes_string.html – niczky12 Mar 10 '16 at 06:51
  • @niczky12 please write an answer to ur suggestion. I did this already and would delete it then. I also guess this is the solution. – drmariod Sep 19 '16 at 09:11
  • @drmariod Thanks for that. Your answer was [mentioned](http://chat.stackoverflow.com/transcript/message/32932593#32932593) in the [R Public Chatroom](http://chat.stackoverflow.com/rooms/25312/r-public) and hence we were able to find that out. Do visit us in your free time! – Bhargav Rao Sep 19 '16 at 13:40

1 Answers1

5

As suggested in my comment, you should use aes_string() to programmatically pass in arguments into ggplot. The error you are getting is because 'input' is a character value while aes() expects unquoted names. Here is how you should replace the call to aes(mpg, input$variable):

myPlot1 <- reactive({
    p <- print(ggplot(mpgData, aes_string('mpg', input$variable)) +
    geom_line())
})
niczky12
  • 4,953
  • 1
  • 24
  • 34
  • Cool! Thanks for settling that @niczky12 – Jonny Sep 19 '16 at 14:44
  • @niczky12, i tried your solution. But when i click on download, the same page is opening another tab.[Here is my code which i have used](https://rcloud.social/edit.html?notebook=b19713397aed79e0a9aa570c4c30025f). [This is shiny page](https://rcloud.social/shiny.html?notebook=b19713397aed79e0a9aa570c4c30025f) – GANA Oct 13 '16 at 11:59