एक चमकदार एप्लिकेशन में किए गए भूखंडों को बचाएं


85

मैं यह पता लगाने की कोशिश कर रहा हूं कि चमकदार के साथ एक भूखंड को बचाने के लिए डाउनलोडबटन का उपयोग कैसे करें। पैकेज में उदाहरण एक .csv को बचाने के लिए डाउनलोडबटन / डाउनलोडहैंडलर प्रदर्शित करता है। मैं उसी के आधार पर एक प्रतिलिपि प्रस्तुत करने योग्य उदाहरण बनाने जा रहा हूं।

के लिये ui.R

shinyUI(pageWithSidebar(
  headerPanel('Downloading Data'),
  sidebarPanel(
selectInput("dataset", "Choose a dataset:", 
            choices = c("rock", "pressure", "cars")),
    downloadButton('downloadData', 'Download Data'),
    downloadButton('downloadPlot', 'Download Plot')
  ),
  mainPanel(
    plotOutput('plot')
  )
))

के लिये server.R

library(ggplot2)
shinyServer(function(input, output) {
  datasetInput <- reactive({
    switch(input$dataset,
           "rock" = rock,
           "pressure" = pressure,
           "cars" = cars)
  })

  plotInput <- reactive({
    df <- datasetInput()
    p <-ggplot(df, aes_string(x=names(df)[1], y=names(df)[2])) +
      geom_point()
  })

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

  output$downloadData <- downloadHandler(
    filename = function() { paste(input$dataset, '.csv', sep='') },
    content = function(file) {
      write.csv(datatasetInput(), file)
    }
  )
  output$downloadPlot <- downloadHandler(
    filename = function() { paste(input$dataset, '.png', sep='') },
    content = function(file) {
      ggsave(file,plotInput())
    }
  )
})

यदि आप इस प्रश्न का उत्तर दे रहे हैं, तो आप शायद इससे परिचित हैं, लेकिन इस कार्य को करने के लिए, उपरोक्त लिपियों को ( ui.Rऔर server.Rएक फ़ोल्डर में foo) कार्यशील निर्देशिका में सहेजें । चमकदार ऐप को चलाने के लिए, रन करें runApp("foo")

का उपयोग करते हुए ggsave, मुझे एक त्रुटि संदेश मिलता है जो यह दर्शाता है कि ggsave filenameफ़ंक्शन का उपयोग नहीं कर सकता है (मुझे लगता है)। अगर मैं मानक ग्राफिक्स डिवाइस (जैसे नीचे) का उपयोग करता हूं, तो Download Plotत्रुटि के बिना काम करता है, लेकिन यह ग्राफिक नहीं लिखता है।

डाउनलोड करने के लिए कोई भी सुझाव प्राप्त करने के लिए प्लॉट लिखने के लिए काम करने वाले को सराहना मिलेगी

जवाबों:


69

निश्चित नहीं है कि यह प्रश्न अभी भी सक्रिय है, लेकिन यह पहला है जो "चमकदार ऐप में भूखंडों की बचत" की खोज करते समय आया था, इसलिए मैं जल्दी से जोड़ना चाहता था कि मूल प्रश्न की तर्ज पर डाउनलोडहैंडलर के साथ काम करने के लिए कैसे ggsave प्राप्त करें।

जुबा द्वारा सुझाए गए वैकल्पिक रणनीतियों को ggsave के बजाय प्रत्यक्ष आउटपुट का उपयोग करके सुझाया गया और वैकल्पिक रणनीति जिसका उपयोग एलेक्सवान ने खुद किया है, दोनों ही महान काम करते हैं, यह सिर्फ उन लोगों के लिए है जो डाउनलोडहैंडलर में ggsave का उपयोग करना चाहते हैं)।

Alexwhan द्वारा बताई गई समस्या ggsave द्वारा सही ग्राफिक्स डिवाइस में फाइल एक्सटेंशन से मिलान करने की कोशिश के कारण होती है। हालाँकि, अस्थायी फ़ाइल में एक्सटेंशन नहीं है इसलिए मिलान विफल हो जाता है। यह ggsaveफ़ंक्शन कॉल में डिवाइस को विशेष रूप से सेट करके फिर से बनाया जा सकता है , जैसे मूल कोड उदाहरण में (एक पीएनजी के लिए):

output$downloadPlot <- downloadHandler(
    filename = function() { paste(input$dataset, '.png', sep='') },
    content = function(file) {
        device <- function(..., width, height) grDevices::png(..., width = width, height = height, res = 300, units = "in")
        ggsave(file, plot = plotInput(), device = device)
    }
)

इस कॉल मूल रूप से लेता है deviceएक के लिए समारोह pngहै कि ggsaveआंतरिक रूप प्रदान करती है (आप देख सकते हैं ggsaveसमारोह कोड के लिए वाक्यविन्यास को देखने के लिए jpg, pdf, आदि)। शायद, आदर्श रूप से, कोई फ़ाइल एक्सटेंशन (यदि फ़ाइल नाम से अलग - अस्थायी फ़ाइल के लिए यहां मामला है) को एक ggsaveपैरामीटर के रूप में निर्दिष्ट कर सकता है, लेकिन यह विकल्प वर्तमान में उपलब्ध नहीं है ggsave


एक न्यूनतम स्व-कार्यशील उदाहरण:

library(shiny)
library(ggplot2)
runApp(list(
  ui = fluidPage(downloadButton('foo')),
  server = function(input, output) {
    plotInput = function() {
      qplot(speed, dist, data = cars)
    }
    output$foo = downloadHandler(
      filename = 'test.png',
      content = function(file) {
        device <- function(..., width, height) {
          grDevices::png(..., width = width, height = height,
                         res = 300, units = "in")
        }
        ggsave(file, plot = plotInput(), device = device)
      })
  }
))

sessionInfo()
# R version 3.1.1 (2014-07-10)
# Platform: x86_64-pc-linux-gnu (64-bit)
# 
# locale:
#  [1] LC_CTYPE=en_US.UTF-8       LC_NUMERIC=C              
#  [3] LC_TIME=en_US.UTF-8        LC_COLLATE=en_US.UTF-8    
#  [5] LC_MONETARY=en_US.UTF-8    LC_MESSAGES=en_US.UTF-8   
#  [7] LC_PAPER=en_US.UTF-8       LC_NAME=C                 
#  [9] LC_ADDRESS=C               LC_TELEPHONE=C            
# [11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C       
# 
# attached base packages:
# [1] stats     graphics  grDevices utils     datasets  methods   base     
# 
# other attached packages:
# [1] ggplot2_1.0.0 shiny_0.10.1 
# 
# loaded via a namespace (and not attached):
#  [1] bitops_1.0-6     caTools_1.17     colorspace_1.2-4 digest_0.6.4    
#  [5] formatR_1.0      grid_3.1.1       gtable_0.1.2     htmltools_0.2.6 
#  [9] httpuv_1.3.0     labeling_0.2     MASS_7.3-34      munsell_0.4.2   
# [13] plyr_1.8.1       proto_0.3-10     Rcpp_0.11.2      reshape2_1.4    
# [17] RJSONIO_1.3-0    scales_0.2.4     stringr_0.6.2    tools_3.1.1     
# [21] xtable_1.7-3    

अपडेट करें

Ggplot2 संस्करण 2.0.0 के रूप में, ggsaveफ़ंक्शन deviceपैरामीटर के लिए वर्ण इनपुट का समर्थन करता है , जिसका अर्थ है कि डाउनलोडहैंडलर द्वारा बनाई गई अस्थायी फ़ाइल को अब प्रत्यक्ष कॉल के साथ ggsaveयह निर्दिष्ट करके बचाया जा सकता है कि उपयोग किए जाने वाले एक्सटेंशन को उदाहरण के लिए "pdf"(पास होने के बजाय) किया जाना चाहिए एक डिवाइस फ़ंक्शन में)। यह उपरोक्त उदाहरण को निम्नलिखित के लिए सरल करता है

output$downloadPlot <- downloadHandler(
    filename = function() { paste(input$dataset, '.png', sep='') },
    content = function(file) {
        ggsave(file, plot = plotInput(), device = "png")
    }
)

1
मेरा मानना ​​है कि आपका उत्तर वास्तव में यहाँ सही है। आप केवल ggsave(file, plotInput(), device = png)डिवाइस (आवरण) फ़ंक्शन बनाने के बजाय उपयोग कर सकते हैं ।
यिहुई एक्सई

@sebkopf मैंने हस्तक्षेप करने वाले वर्ष में आपका उत्तर याद किया और थोड़ा सा!
अलेवहान

1
@ यिहुई यह समाधान मेरे लिए काम नहीं करता है: आर संस्करण 3.1.0, ggplot2_1.0.0 चमकदार_0.10.1। सहेजें बॉक्स पॉप अप, सहेजें पर क्लिक करें, लेकिन कोई फ़ाइल सहेजी नहीं गई है। क्या कोई पुष्टि कर सकता है?
zx8754

3
@ zx8754 मैंने केवल उत्तर के लिए एक पूर्ण उदाहरण जोड़ा। ध्यान दें कि आपको इसे RStudio में देखने के बजाय अपने वेब ब्राउज़र में चलाना चाहिए, क्योंकि RStudio दर्शक के पास फ़ाइलों को डाउनलोड करने में असमर्थ होने का एक ज्ञात बग है।
यिहुई Xie

1
@sebkopf हां, जब मैंने वास्तविक उदाहरण की कोशिश की, तब मुझे इसका एहसास हुआ, इसलिए यहां मेरी पहली टिप्पणी वास्तव में गलत थी। स्पष्टीकरण के लिए धन्यवाद!
यिहुई एक्सई

24

यहां एक समाधान है जो चमकदार भूखंडों को बचाने के लिए गैगसेव का उपयोग करने की अनुमति देता है। यह कॉल करने के लिए एक तार्किक चेकबॉक्स और टेक्स्ट इनपुट का उपयोग करता है ggsave()। इसे ui.Rफ़ाइल के अंदर जोड़ें sidebarPanel:

textInput('filename', "Filename"),
checkboxInput('savePlot', "Check to save")

फिर इसे server.Rमौजूदा output$plotरिएक्टिवप्लॉट फ़ंक्शन के बजाय फ़ाइल में जोड़ें :

output$plot <- reactivePlot(function() {
    name <- paste0(input$filename, ".png")
    if(input$savePlot) {
      ggsave(name, plotInput(), type="cairo-png")
    }
    else print(plotInput())
  })

उपयोगकर्ता तब टेक्स्टबॉक्स में वांछित फ़ाइल नाम टाइप कर सकता है (विस्तार के बिना) और ऐप निर्देशिका में सहेजने के लिए चेकबॉक्स पर टिक करें। बॉक्स को अनचेक करने से प्लॉट फिर से प्रिंट हो जाता है। मुझे यकीन है कि ऐसा करने के नीटर तरीके हैं, लेकिन कम से कम अब मैं बहुत अच्छे अच्छे png ग्राफिक्स के लिए विंडोज़ में ggsave और cairo का उपयोग कर सकता हूं।

कृपया अपने पास कोई सुझाव जोड़ें।


बिना किसी isolateखंड के चारों ओर input$filename, filenameटेक्स्ट बॉक्स में कोई भी परिवर्तन, फ़ाइल की जाँच करने पर एक फ़ाइल सेव का संकेत देगा।
jpd527

23

मैंने इसके साथ काम करने का प्रबंधन नहीं किया ggsave, लेकिन एक मानक कॉल के साथ png()यह ठीक प्रतीत होता है।

मैंने केवल output$downloadPlotआपकी server.Rफ़ाइल का हिस्सा बदला है :

 output$downloadPlot <- downloadHandler(
    filename = function() { paste(input$dataset, '.png', sep='') },
    content = function(file) {
      png(file)
      print(plotInput())
      dev.off()
    })

ध्यान दें कि मुझे चमकदार 0.3 संस्करण के साथ कुछ समस्याएं थीं, लेकिन यह गितुब के नवीनतम के साथ काम करता है:

library(devtools)
install_github("shiny","rstudio")

ठीक है, मैं स्वीकार करने जा रहा हूँ कि ggsave डाउनलोडहैंडलर के साथ कार्यवाही के इस स्तर पर काम नहीं करने वाला है। चमकदार 0.3 डाउनलोडहैंडलर के साथ अलग हो जाता है, आप सही हैं। मैं एक वैकल्पिक समाधान पोस्ट करूँगा जिसे मैंने डाउनलोडहैंडलर से बचने के लिए सोचा था जो कि गैगसेव को काम करने देगा।
अलेक्सवां

1
@ जुबा किसी भी विचार क्यों यह एक समान (गैर- ggplot2) विधि के साथ पीडीएफ के उत्पादन का प्रयास काम नहीं करता है? मुझे बस एक टूटी हुई पीडीएफ मिल रही है जो नहीं खुलती है। क्या प्लॉट ऑब्जेक्ट के बदले प्लॉट इंप्यूट नहीं कर सकता है?
जियोथेट्री

20

यह पुराना है, लेकिन फिर भी शीर्ष हिट होता है जब कोई व्यक्ति "आर चमकदार चमकदार ggplot" को गोगल्स करता है, तो मैं एक और वर्कअराउंड में योगदान दूंगा। बहुत सरल ... उसी ग्राफ़ में कॉल करें जो आपके ग्राफ़ को प्रदर्शित करता है, जो सर्वर पर फ़ाइल के रूप में ग्राफ़ को बचाएगा।

output$plot <- renderPlot({
    ggsave("plot.pdf", plotInput())
    plotInput()
})

फिर, डाउनलोडहैंडलर का उपयोग करें और file.copy()मौजूदा फ़ाइल से डेटा को "फ़ाइल" पैरामीटर में लिखने के लिए उपयोग करें।

output$dndPlot <- downloadHandler(
    filename = function() {
        "plot.pdf"
    },
    content = function(file) {
        file.copy("plot.pdf", file, overwrite=TRUE)
    }
)

मेरे लिये कार्य करता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.