r - 仅当打印输入变量时,闪亮的反应式才有效
问题描述
我正在我的一个闪亮的应用程序中创建 Joyplot。它允许用户使用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
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"
),
actionButton("plot" , label = "Plot"),
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 = 0.5 - abs(0.5 - ..ecdf..)),
calc_ecdf = TRUE) +
viridis::scale_fill_viridis(name = "quantile" , option = input$joy_plot_fill, discrete = F)
return(ggjoy_plot)
})
output$joyplot <- renderPlot({
jp()
})
}
)
解决方案
利用 -
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
foroutput$joyplot
并作为参数传递时input$joy_plot_fill
,您本质上是在确保它在尝试渲染绘图时做出明智的优化选择。
做出plot_data
反应式的好举动,现在称为反应式导体,但只有在数据很大并且您不想运行它超过绝对必要的次数时才重要。
更新
对于这个print
问题,我会尝试解释。
该reactive
功能本质上是试图尽可能少地执行。如果某些输入发生变化,如果检测到对该输入的依赖,则触发反应块。
在您将input$joy_plot_fill
作为参数传递给ggplot
函数的情况下,反应块无法访问该代码并检测到更改(因为它是函数内部的参数)。
这不是特定的打印问题。尝试将打印行更改为abcd <- input$joy_plot_fill
- 再次,这没有任何作用,但不知何故,这会引起响应式对该输入组件的注意,因此它会再次执行。
尝试在函数之前设置断点jp
并逐行调试,您就会知道我在说什么。
更新 2
我确实得到了你想说的,但不幸的是它几乎无法解释。
这里肯定会为您工作。
- 在启动闪亮的应用程序之前,设置
options(shiny.reactlog=TRUE)
- 在可行的情况下 (
ecdf
),启动闪亮的应用程序,单击A
,然后按Ctrl+F3
。这将显示反应器执行沿袭图。在这里,您会看到它需要以某种方式重新计算/重新评估表达式0.5 - abs(0.5 - ..ecdf..)
,因此绘图会呈现,因为现在存在直接依赖关系(我知道这听起来很模糊,但是一旦您看到执行图,您就会知道我在说什么) - 在不起作用的情况下(
quantile
),您会注意到它以某种方式不需要执行 ggplot 语句,因为它缓存了所有对象并且不需要重新计算quantile
。(再次,您将在看到图表后知道)
希望有帮助!圣诞节快乐!!!
推荐阅读
- elasticsearch - Elastci 搜索:在数组字段上完全匹配
- python - 如何运行作为 Python GUI 输入的示例代码?
- jenkins - 电子邮件分机插件模板未更新
- html - 在网格布局中设置图像以在悬停时更改
- apache-kafka - Kafka 的 __consumer_offsets 中的消息时间戳和 commit_timestamp
- tensorboard - 多个数据集之间的 Tensorboard 投影仪动画转换
- jupyter - JupyterHub Spawn 第一次安装报错
- c++ - VS2019:如何解决资源视图中的“未知子语言:0x8”消息?
- c# - 如何清除 Cefsharp (Chromium) 代理缓存以更改代理凭据?
- windows - 为什么我的 Anaconda 提示修饰符显示完整的环境路径?