2016-07-14 13 views
8

Ich verwende eine Kombination aus Shiny und Knitr, um PDF-Dokumente zu erstellen.Bild wird über Shiny in das Knitr-Dokument hochgeladen

Momentan möchte ich eine Funktion hinzufügen, mit der Benutzer Bilder hochladen können, die in das erstellte Dokument eingefügt werden. Ich stecke jedoch wirklich fest, weil ich den Pfad des Eingangsbildes nicht erkennen kann. Könnte mir jemand dabei helfen?

Einfaches Beispiel:

Anwendung:

library(knitr) 
library(shiny) 

ui <- fluidPage(

    sidebarLayout(
    sidebarPanel(
     fileInput("picture", label = 'Picture'), 
     downloadButton('report', label = 'Download PDF') 
    ), 

    mainPanel() 
) 
) 

server <- function(input,output){ 

    picture <- reactive({ 
    input$picture[,4] 
    }) 

    output$report = downloadHandler(
    filename = "test.pdf", 

    content = function(file){ 
     picture = picture() 

    out = knit2pdf(input = 'test.Rnw', compiler = 'xelatex', clean = TRUE) 
    file.rename(out, file) 
    }, 

    contentType = 'application/pdf' 
) 
} 

shinyApp(ui = ui, server = server) 

und das .Rnw Dokument:

\documentclass{article} 

\begin{document} 

Put picture here: 
<<echo = FALSE , message = F, results='asis'>>= 
cat(paste('\\includegraphics[height=3in]{', picture,'}')) 
@ 

\end{document} 

Teil '\includegraphics[height=3in]{', picture,'} offensichtlich das Problem verursacht, weil ich weiß nicht, den Bildpfad nur vorübergehend ein.

+1

hochgeladen Dateipfad ist 'Eingang $ Bild datapath' –

+0

Ja $, aber es ist Pfad zu temporäres Verzeichnis, und ich habe keine Ahnung, wie es funktioniert. Außerdem ist $ datapath gleich wie [, 4] in meinem Code. –

+0

Versuchen Sie 'paste' durch' paste0' in Ihrer '.Rnw' Datei zu ersetzen, da sonst hinter dem Dateinamen ein Leerzeichen steht und das Bild nicht gefunden wird. – NicE

Antwort

2

Sie sagten, Sie mit glänzenden Server gearbeitet haben, dann sollten Sie mit dem vollständigen Pfad von der Ordnung sein Bild, auch wenn es in einem temporären Verzeichnis ist (weil Shiny Server derzeit nur unter Linux funktioniert und LaTeX sollte mit Linux-Dateipfaden wie /tmp/...../yourfile.png in Ordnung sein). Das Problem ist vielleicht die datapath (d. H. input$picture[, 4]) hat nicht die Dateierweiterung, so LaTeX konnte es nicht erkennen. Sie können versuchen, die Dateinamenserweiterung der ursprünglichen Datei abzurufen und das hochgeladene Bild in eine temporäre Datei mit derselben Erweiterung zu kopieren, z.

picture <- reactive({ 
    path1 <- input$picture$datapath 
    path2 <- tempfile(fileext = gsub('^(.*)([.].+)$', '\\2', input$picture$name)) 
    file.copy(path1, path2, overwrite = TRUE) 
    path2 
}) 
+0

vielen dank für die antwort aber ich laufe immer noch auf den fehler 'running 'tex2dvi' auf 'test.tex' fehlgeschlagen. LaTeX Fehler: ! LaTeX Fehler: Datei '/ tmp/RtmpoSS6qz/4683e6ec5bcf520337300eb1/0' nicht gefunden. "Ich vermisse wahrscheinlich etwas sehr einfaches, aber ich kann es wirklich nicht herausfinden. –

+0

Weiterhin habe ich die reaktive Funktion' picture() 'zu einfach' bild' mit der 'content = funktion (datei) {bild = pi cture() ' –

+0

Ich verstehe. Entschuldigung, das habe ich nicht verstanden. Wird die Antwort in einer Minute aktualisieren. –

1

ich sehe eine Lösung auf zwei Arten:

1) in einen Ordner Ihrer Wahl die temporäre Datei kopieren und das Bild verwenden:

observe({ 
     if (is.null(input$picture)) return() 
     picture<-"your/final/path/to/disk/uploadImage.jpg" # OR do a PASTE with the PATH and the upload file name 
     file.copy(input$picture$datapath, picture) 
     if(file.exists(picture)){ 
      # PROCESS THE IMAGE IF NEEDED 
     } 
     picture<<-picture # sometimes needed to R to see the variable outside the observe scope 
}) 

2), wenn Sie (in diesem Fall der R session) dürfen nicht auf die Festplatte schreiben, Sie können das Bild in eine base64-Variable umwandeln und diese in Ihr Knitr-Dokument einfügen (oder es als String in einer Datenbank speichern). Dies nimmt die Knitr/HTML-Route, wenn Sie bereit sind, diesen Umweg zu nehmen. (R Studio, das von einem Server läuft, hat fast immer viele Einschränkungen beim Lesen/Schreiben, die Sie nur als ADMIN handhaben können. Und der Server führt die glänzende Sitzung als RStudio aus, und nicht Sie, wenn Rstudio die Lese-/Schreibberechtigungen benötigt Sie führen die Shiny-App als automatische Rstudio Shiny-Sitzung aus und nicht direkt in RStudio mit RUN)

Stellen Sie sicher, dass base64 mit "< - < -" wieder aus dem Bereich "Beobachten" oder "Wenn" gelesen werden kann. 'zusammen mit' < - '. Scoping ist mit R etwas ganz besonderes, also teste es richtig.

Sie sollten in diesem (base64) tauchen mit Seiten wie:

https://github.com/yihui/knitr/issues/944

https://github.com/yihui/knitr/blob/master/R/utils-base64.R

+0

Vielen Dank für die Antwort. Ich werde an der Implementierung arbeiten und Sie wissen lassen, ob Ihr Ansatz es mir erlaubt hat, das Problem zu lösen. Wie Sie bereits erwähnt haben, arbeite ich eigentlich mit Shiny Server, daher gibt es Probleme beim Schreiben von Berechtigungen. Deshalb habe ich die hier angebotene Lösung [http://stackoverflow.com/questions/35800883/using-image-in-r-markdown-report-downloaded-from-shiny-app] verwendet, aber für einige vordefinierte Bilder welche sind auf dem Server platziert. Ich frage mich, ob es auf diesen Fall angewendet werden könnte, wenn das Bild vom Benutzer hochgeladen wird? –

+0

@Akonomist, ich würde immer mit vollständigen Systempfaden arbeiten (je nach System beginnend von der ROOT mit C:/.... oder/.../... oder .. und hoffe nicht, es in der Gleicher oder naher Ordner Kann funktionieren, aber einige R-Programmierer verschieben gerne ihr Arbeitsverzeichnis (mit setwd() und getwd() --- >>> nicht ich aber = ^) und dann bist du im Blind .... Du kann übrigens immer das temp-dateiverzeichnis mit der funktion aufrufen: tempdir() – irJvV