【问题标题】:Use reactive variable to plot histogram using plotly使用反应变量使用 plotly 绘制直方图
【发布时间】:2019-06-14 10:23:53
【问题描述】:

我正在尝试制作一个应用程序,用户可以在其中浏览文件,然后从列名列表中选择任何特定列,然后绘制直方图。此外,我想给用户一个选项来删除异常值,这是一个复选框输入。如果单击该复选框,则会删除异常值并再次绘制直方图。简而言之,直方图对用户在复选框中所做的选择做出反应。当在复选框上观察到观察事件时,我无法绘制图表。我认为当我将数据创建为响应式时,它没有被适当地引用。

我不确定如何在这里准确地使用反应性。如果我不使用反应性,那么我会收到一个错误,即我的数据集在 observeEvent 函数下不可用(可能是本地函数的情况)

df_data <- reactiveValues(data= NULL)

observeEvent(input$filename,{
  df_data$data <- data.frame(read.csv(input$filename$datapath))
  updateSelectInput(session,"field_mapping",choices = colnames(df_data$data))
  updateCheckboxInput(session,"outlier_removal",value = TRUE)
})

observeEvent(input$outlier_removal,{
if(input$outlier_removal)
{ cash_diff <- removeOutliers(createCashDiff(as.vector(df_data$data[,input$field_mapping]),input$percent_change)) }
else { cash_diff <- removeOutliers(createCashDiff(as.vector(df_data$data[,input$field_mapping]),input$percent_change)) }
output$Histogram <- renderPlotly({ plotDiff(cash_diff) })
})

【问题讨论】:

    标签: r shiny reactive


    【解决方案1】:

    我认为您不应该尝试从 observe 块内进行绘图。更重要的是,observeEvent 的表达式(第二个参数)中的内容是明确完成的,没有反应性副作用,因此可以说它是绝缘/屏蔽的。

    试试这个:

    df_data <- reactiveValues(data= NULL)
    
    observeEvent(input$filename,{
      df_data$data <- data.frame(read.csv(input$filename$datapath))
      updateSelectInput(session,"field_mapping",choices = colnames(df_data$data))
      updateCheckboxInput(session,"outlier_removal",value = TRUE)
    })
    
    df_data_filtered <- reactive({
      x <- createCashDiff(as.vector(df_data$data[,input$field_mapping]),input$percent_change)
      if (input$outlier_removal) x <- removeOutliers(x)
      x
    })
    
    output$Histogram <- renderPlotly({ plotDiff(df_data_filtered()) })
    

    旁注:您在if (input$outlier_removal) 条件的两侧都执行完全相同的函数调用。这是否意味着您的createCashDiffremoveOutliers 函数自己获得input$outlier_removal 值?我认为这将是一个糟糕的举动,原因有两个:

    1. 类似的函数应该与在闪亮内部或外部使用无关,因此您可以在控制台/测试(非闪亮)环境中进行开发和测试。在函数内部嵌入对“反应性”(甚至只是input$)的依赖限制了函数的潜力;和

    2. 一般而言,编写函数的良好做法包括确保它们永远不会尝试访问未 (a) 显式传递给它们或 (b) 在函数中定义(直接或通过另一个函数)的变量或对象称呼)。当您有一个函数访问其直接范围之外的变量时,测试和再现性会变得更加复杂,并且当它们行为不端时要排除故障会变得更加困难。

    【讨论】:

    • 非常感谢@r2evans。你是个天才。我需要更多地研究反应性才能在我的应用程序中使用它。你的解释很精彩。这现在有效。而且,是的.. 抱歉,我将 removeOutliers 函数置于这两种条件下.. 它应该只在 input$outlier_removal 为真时才适用。
    • 是的。我能够使用它运行和测试应用程序。再次感谢:-)
    • Reactivity 是一个非常强大的——有时是混乱的——工具。我发现自己手动绘制依赖关系流程图,考虑到isolate 甚至意外的读/写操作。最后,我查看reactlog 以了解shiny 认为反应性关系是什么,然后意识到为什么一个字段中的单个更改可能会导致表格或绘图多次重新渲染。一般来说,我发现最好“在reactive 块中简单地处理数据,然后在简单的render* 函数中依赖它”
    猜你喜欢
    • 2021-03-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-27
    • 2017-08-11
    • 2016-06-09
    相关资源
    最近更新 更多