闪亮的反应式仅在打印输入变量时有效

时间:2018-12-25 05:27:05

标签: r shiny reactive

我正在其中一个闪亮的应用程序中创建Joyplot。它允许用户使用run_test.py选择填充颜色。我在这里要做的是,首先通过radioGroupButtons生成图,然后在reactive内部使用无功输出。请参阅下面给出的最少代码。问题是,只有在我打印输入变量renderPlot (反应式中的第一行)时,reactive中的代码才会执行​​。否则不行。任何帮助将不胜感激。

print(input$joy_plot_fill)

=====更新=========

library(shiny) library(shinyWidgets) library(tidyverse) library(viridis) library(ggridges) shinyApp( ui = fluidPage( shinyWidgets::radioGroupButtons( inputId = "joy_plot_fill", label = "Fill choices", individual = T, choices = c("A" = "A", "B" = "B", "C" = "C", "D" = "D", "E" = "E"), selected = "C" ), plotOutput(outputId = "joyplot") ), server = function(input, output, session) { plot_data <- reactive({ plot_data <- mtcars %>% as_tibble() %>% dplyr::select(mpg,cyl,disp,hp,drat) plot_data_l <- plot_data %>% tidyr::gather(variable, value) return(plot_data_l) }) jp <- reactive({ #print(input$joy_plot_fill) ggjoy_plot <- ggplot(plot_data()) + ggridges::stat_density_ridges(geom = "density_ridges_gradient" , mapping = aes(x = value, y = variable, fill = ..quantile..), calc_ecdf = TRUE , quantiles = 4, quantile_lines = T) + viridis::scale_fill_viridis(name = "Prob" , option = input$joy_plot_fill, discrete = T) return(ggjoy_plot) }) output$joyplot <- renderPlot({ jp() }) } ) 内部的填充从ggridges::stat_density_ridges更改为..quantile..,即使0.5 - abs(0.5 - ..ecdf..)中没有print行,也可以通过概率而不是分位数填充颜色。请参见下面的代码。我不了解在第二种情况下反应式块如何发出警报,而在第一种情况下则不然。

reactive

1 个答案:

答案 0 :(得分:1)

使用-

shinyApp(
  ui = 
    fluidPage(
      shinyWidgets::radioGroupButtons(
        inputId = "joy_plot_fill",
        label = "Fill choices", individual = T,
        choices = c("A" = "A", "B" = "B", "C" = "C", "D" = "D", "E" = "E"),
        selected = "C"
      ),

      plotOutput(outputId = "joyplot")
    ),

  server =
    function(input, output, session) {

      plot_data <- reactive({
        plot_data <- mtcars  %>% as_tibble() %>% dplyr::select(mpg,cyl,disp,hp,drat)
        plot_data_l <- plot_data %>% tidyr::gather(variable, value)
        return(plot_data_l) 

      })

      output$joyplot <- renderPlot({
        ggplot(plot_data()) +
          ggridges::stat_density_ridges(geom = "density_ridges_gradient" , 
                                        mapping = aes(x = value, y = variable, fill = ..quantile..), 
                                        calc_ecdf = TRUE , quantiles = 4, quantile_lines = T) +
          viridis::scale_fill_viridis(name = "quantile" , option = input$joy_plot_fill, discrete = T)
      })

    }
)

说明

reactive的概念变得简单。

  

在Shiny中,反应式编程包含三种对象:   反应源,反应导体和反应终点

来源是用户输入(在您的情况下为input$joy_plot_fill)。反应性端点通常是出现在用户浏览器窗口中的内容,例如output$joyplot

因此,当您将renderPlot用作output$joyplot并传递input$joy_plot_fill作为参数时,本质上是在尝试渲染绘图时确保它做出了明智的优化选择。

通过使plot_data具有反应性而进行了很好的移动,现在 被称为反应性导体,但是只有在数据量很大并且您不想运行更多数据的情况下,这才有意义比绝对必要的时间还多。

更新

对于print问题,我将尝试解释。

reactive函数本质上是在尝试尽可能少地执行。如果某些输入发生更改,则反应模块如果检测到对该输入的依赖性,则会触发该模块。

在您将input$joy_plot_fill作为参数传递给ggplot函数的情况下,反应式块无法到达该代码并检测到更改(因为它是函数内部的参数)

这不是特定的打印问题。尝试将打印行更改为abcd <- input$joy_plot_fill-再次,此操作无济于事,但不知何故,这引起了react对这个输入组件的注意,因此它再次执行。

尝试在jp函数之前设置一个断点,然后逐行调试,您将了解我在说什么。

更新2

我确实听懂了您想说的话,但不幸的是,几乎无法解释。

这将是绝对为您工作的。

  1. 启动闪亮的应用程序之前,请先设置options(shiny.reactlog=TRUE)
  2. 在有效的情况下(ecdf,启动闪亮的应用程序,单击A,然后按Ctrl+F3。这将得出反应堆执行沿袭图。在这里,您将看到它需要以某种方式重新计算/重新评估表达式0.5 - abs(0.5 - ..ecdf..),因此该图呈现出来,因为现在存在直接依赖项(我知道这听起来很模糊,但是一旦您看到执行图,您就会知道我在说)
  3. 在不起作用(quantile)的情况下,您会注意到它以某种方式不需要执行ggplot语句,因为它已缓存了所有对象并且不需要重新计算{{1 }}。 (同样,一旦看到图表,您就会知道)

希望有帮助!圣诞快乐!!!