不允许从闪亮的输出对象中读取对象? [英] Reading objects from shiny output object not allowed?

查看:48
本文介绍了不允许从闪亮的输出对象中读取对象?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试编写一个小应用程序,该应用程序将允许用户制作散点图,在图中选择一个点的子集,然后以 .csv 格式输出一个表格,其中仅包含这些选定的点.我想出了如何启动和运行页面以及如何使用刷点选择点.出现带有选定点的表格,但是当我按下下载按钮时,出现错误不允许从shinyoutput 对象读取对象".出现.我是否无法下载可以在屏幕上直观看到的 .csv 表格?如果是这样,是否有解决方法?

I'm trying to write a little app that will allow the user to make a scatterplot, select a subset of points on the plot, then output a table in .csv format with just those selected points. I figured out how to get the page up and running and how to select points using brushedPoints. The table with selected points appears but when I press the Download button, the error "Reading objects from shinyoutput object not allowed." appears. Am I unable to download the table that I can visually see on the screen as a .csv? If so, is there a workaround?

我使用下面的 iris 数据集重现了这个问题.任何帮助弄清楚为什么我无法下载显示的行表的帮助将不胜感激.

I've recreated the problem using the iris dataset below. Any help figuring out why I cannot download the table of displayed rows would be greatly appreciated.

data(iris)

ui <- basicPage(
  plotOutput("plot1", brush = "plot_brush"),
  verbatimTextOutput("info"),mainPanel(downloadButton('downloadData', 'Download'))
)


server <- function(input, output) {
  output$plot1 <- renderPlot({
ggplot(iris,aes(x=Sepal.Width,y=Sepal.Length)) +
    geom_point(aes(color=factor(Species))) + 
    theme_bw()
  })

  output$info <- renderPrint({
brushedPoints(iris, input$plot_brush, xvar = "Sepal.Width", yvar = "Sepal.Length")
  })

  output$downloadData <- downloadHandler(
      filename = function() { 
        paste('SelectedRows', '.csv', sep='') },
        content = function(file) {
        write.csv(output$info, file)
      }
  )

}


shinyApp(ui, server)

推荐答案

问题是输出对象也生成了所有的 Web 显示内容.相反,您需要单独提取数据以进行下载.您可以通过在下载代码中再次调用 brushedPoints 来实现.然而,更好的是使用 reactive() 函数只执行一次,然后在您需要的任何地方调用它.以下是我将如何修改您的代码以使其正常工作:

The issue is that the output object is generating all of the web display stuff as well. Instead, you need to pull the data separately for the download. You could do it with a second call to brushedPoints in the download code. Better, however, is to use a reactive() function to do it just once, then call that everywhere that you need it. Here is how I would modify your code to make that work:

data(iris)

ui <- basicPage(
  plotOutput("plot1", brush = "plot_brush"),
  verbatimTextOutput("info"),mainPanel(downloadButton('downloadData', 'Download'))
)


server <- function(input, output) {
  output$plot1 <- renderPlot({
    ggplot(iris,aes(x=Sepal.Width,y=Sepal.Length)) + geom_point(aes(color=factor(Species))) + theme_bw()
  })


  selectedData <- reactive({
    brushedPoints(iris, input$plot_brush)
  })

  output$info <- renderPrint({
    selectedData()
  })

  output$downloadData <- downloadHandler(
    filename = function() { 
      paste('SelectedRows', '.csv', sep='') },
    content = function(file) {
      write.csv(selectedData(), file)
    }
  )

}


shinyApp(ui, server)

(注意,使用ggplot2,您不需要在brushedPoints 中显式设置xvaryvar.所以,我这里去掉了,以增加代码的灵活性.)

(Note, with ggplot2, you do not need to explicitly set xvar and yvar in brushedPoints. So, I removed it here to increase the flexibility of the code.)

我不知道 shiny 中有任何套索"风格的免费绘图功能(不过,给它一周时间——他们不断添加有趣的工具).但是,您可以通过允许用户选择多个区域和/或单击单个点来模拟行为.服务器逻辑变得更加混乱,因为您需要将结果存储在 reactiveValues 对象中以便能够重复使用它.我做了类似的事情,允许我在一个图上选择点并在其他图上突出显示/删除它们.这比你在这里需要的要复杂,但下面应该工作.您可能想要添加其他按钮/逻辑(例如,重置"选择),但我相信这应该可行.我确实在图中添加了选择的显示,以便您跟踪已选择的内容.

I am not aware of any "lasso" style free drawing ability in shiny (though, give it a week -- they are constantly adding fun tools). However, you can mimic the behavior by allowing user to select multiple regions and/or to click on individual points. The server logic gets a lot messier, as you need to store the results in a reactiveValues object to be able to use it repeatedly. I have done something similar to allow me to select points on one plot and highlight/remove them on other plots. That is more complicated than what you need here, but the below should work. You may want to add other buttons/logic (e.g., to "reset" the selections), but I believe that this should work. I did add a display of the selection to the plot to allow you to keep track of what has been selected.

data(iris)

ui <- basicPage(
  plotOutput("plot1", brush = "plot_brush", click = "plot_click")
  , actionButton("toggle", "Toggle Seletion")
  , verbatimTextOutput("info")
  , mainPanel(downloadButton('downloadData', 'Download'))
)


server <- function(input, output) {
  output$plot1 <- renderPlot({

    ggplot(withSelected()
           , aes(x=Sepal.Width
                 , y=Sepal.Length
                 , color=factor(Species)
                 , shape = Selected)) +
      geom_point() +
      scale_shape_manual(
        values = c("FALSE" = 19
                   , "TRUE" = 4)
      , labels = c("No", "Yes")
      , name = "Is Selected?"
      ) +
      theme_bw()
  })

  # Make a reactive value -- you can set these within other functions
  vals <- reactiveValues(
    isClicked = rep(FALSE, nrow(iris))
  )


  # Add a column to the data to ease plotting
  # This is really only necessary if you want to show the selected points on the plot
  withSelected <- reactive({
    data.frame(iris
               , Selected = vals$isClicked)
  })



  # Watch for clicks
  observeEvent(input$plot_click, {

    res <- nearPoints(withSelected()
                      , input$plot_click
                      , allRows = TRUE)

    vals$isClicked <-
      xor(vals$isClicked
          , res$selected_)
  })


  # Watch for toggle button clicks
  observeEvent(input$toggle, {
    res <- brushedPoints(withSelected()
                         , input$plot_brush
                         , allRows = TRUE)

    vals$isClicked <-
      xor(vals$isClicked
          , res$selected_)
  })

  # pull the data selection here
  selectedData <- reactive({
    iris[vals$isClicked, ]
  })

  output$info <- renderPrint({
    selectedData()
  })

  output$downloadData <- downloadHandler(
    filename = function() { 
      paste('SelectedRows', '.csv', sep='') },
    content = function(file) {
      write.csv(selectedData(), file)
    }
  )

}


shinyApp(ui, server)

这篇关于不允许从闪亮的输出对象中读取对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆