Jonny Polonsky Jonny Polonsky - 2 months ago 26
R Question

Producing PDF report using knitr (LaTeX) from Shiny application

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

Answer

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())
})
Comments