我在图表中制作了三个反应层。在下面的可重现示例中,图形以function1绘制开始。如果我检查function2,闪亮重新计算并重绘function1和function2。然后,如果我勾选function3,则重新计算并重新绘制所有3个函数。
假设我想要运行的函数是非常长的推论,每个都需要几分钟。
如何制作它以便在我检查(或取消选中)一个功能时,闪亮不会重新计算并重绘所有已检查的功能?
在下面的代码中,我已经包含了print语句,这些语句显示每次调用renderPlot时都会运行每个被动运行(这是输入$ fun更改时)。
library(shiny)
library(ggplot2)
x <- seq(0, 10, by=0.1)
runApp(shinyApp(
ui = shinyUI(fluidPage(
titlePanel("Test Shiny"),
sidebarLayout(
sidebarPanel(
checkboxGroupInput("fun", label = "Function",
choices = list("function1: x^2" = 1,
"function2: x^2 + x" = 2,
"function3: x^2 - x" = 3),
selected = c(1))
),
mainPanel(
plotOutput("plot")
)
)
)),
server = shinyServer(function(input, output) {
fn1 <- reactive({
print("we are in fn1 <- reactive({})")
if (1 %in% input$fun ) {
geom_line(mapping = aes(x, y=x^2), color="blue") }
})
fn2 <- reactive({
print("we are in fn2 <- reactive({})")
if (2 %in% input$fun) {
geom_line(mapping = aes(x, y=x^2 + x), color="red") }
})
fn3 <- reactive({
print("we are in fn3 <- reactive({})")
if (3 %in% input$fun) {
geom_line(mapping = aes(x, y=x^2 - x), color="green") }
})
output$plot <- renderPlot({
cat("\n we are in output$plot <- renderPlot({}) \n")
ggplot() + fn1() + fn2() + fn3()
})
})
))
我可以使用单个复选框(checkboxInput)实现此效率,但我不想使用单个复选框。单个复选框看起来不太好,除非有办法让它们看起来更像复选框组输入?
我一直试图解决这个问题,并搜索了一段时间。我非常感谢任何帮助!
EDIT
以下是使用基础R plot()
和lines()
响应@Jimbou闪亮代码的一些代码。请参阅@Jimbou提供的闪亮代码下面的评论。
output$plot <- renderPlot({
cat("\n we are in output$plot <- renderPlot({}) \n")
plot(NULL, xlim = c(0,10), ylim = c(0,100))
if(1 %in% input$fun) {
print("we are in if(1 %in% input$fun){} ")
lines(x=x, y=x^2, col=2)
}
if(2 %in% input$fun) {
print("we are in if(2 %in% input$fun){} ")
lines(x=x, y=x^2 + x, col=3)
}
if(3 %in% input$fun) {
print("we are in if(3 %in% input$fun){} ")
lines(x=x, y=x^2 - x, col=4)
}
})
答案 0 :(得分:0)
我认为最接近的是延迟图层处理,直到您单击操作按钮明确告诉服务器何时开始处理图。
library(shiny)
library(ggplot2)
x <- seq(0, 10, by=0.1)
runApp(shinyApp(
ui = shinyUI(fluidPage(
titlePanel("Test Shiny"),
sidebarLayout(
sidebarPanel(
checkboxGroupInput("fun", label = "Function",
choices = list("function1: x^2" = 1,
"function2: x^2 + x" = 2,
"function3: x^2 - x" = 3),
selected = c(1)),
actionButton(inputId = "btn_update_plot",
label = "Update Plot")
),
mainPanel(
plotOutput("plot")
)
)
)),
server = shinyServer(function(input, output) {
p <- eventReactive(
input$btn_update_plot,
{
ggp = ggplot()
if (1 %in% input$fun )
{
ggp <- ggp + geom_line(mapping = aes(x, y=x^2), color="blue")
}
if (2 %in% input$fun)
{
ggp <- ggp + geom_line(mapping = aes(x, y=x^2 + x), color="red")
}
if (3 %in% input$fun)
{
ggp <- ggp + geom_line(mapping = aes(x, y=x^2 - x), color="green")
}
ggp
}
)
output$plot <- renderPlot({
print("we are in output$plot <- renderPlot({})")
p()
})
})
))
答案 1 :(得分:0)
这是一个使用基线R绘图功能和线条的解决方案。
library(shiny)
library(ggplot2)
x <- seq(0, 10, by=0.1)
runApp(shinyApp(
ui = shinyUI(fluidPage(
titlePanel("Test Shiny"),
sidebarLayout(
sidebarPanel(
checkboxGroupInput("fun", label = "Function",
choices = list("function1: x^2" = 1,
"function2: x^2 + x" = 2,
"function3: x^2 - x" = 3),
selected = c(1))
),
mainPanel(
plotOutput("plot")
)
)
)),
server = shinyServer(function(input, output) {
output$plot <- renderPlot({
plot(NULL, xlim = c(0,10), ylim = c(0,100))
if(1 %in% input$fun) lines(x=x, y=x^2, col=2)
if(2 %in% input$fun) lines(x=x, y=x^2 + x, col=3)
if(3 %in% input$fun) lines(x=x, y=x^2 - x, col=4)
})
})
))
答案 2 :(得分:0)
我已经考虑过这样做的方法。在下面的代码中,checkboxGroupInput像以前一样具有选项“function1”,“function2”或“function3”。如果选中“function1”和“function2”,然后用户检查“function3”,则只计算function3。在原始帖子的代码中,有光泽会计算所有三个函数。
checkboxGroupInput中的任何更改都将使这三个响应式表达式无效
fn1 <- reactive({...})
,
fn2 <- reactive({...})
,
fn3 <- reactive({...})
导致它们被重新运行。
但是在下面的新代码中,上面的每个反应式表达式(如果已经检查过)通过另一个反应式表达式返回缓存值
我已经包含了print语句,表明在checkboxGroupInput(“function1”,“function2”或“function3”)中检查或取消选中一个框不会导致Shiny重新计算所有已检查的函数,因为我的原始函数会闪亮上面的代码
我之前提到过使用单个复选框,所以我还提供了一个单一复选框“relation4”的示例,以显示使用单个复选框checkboxInput(),不会导致其他被动不必要地重新运行
NB观看打印到控制台的内容
library(shiny)
library(ggplot2)
runApp(shinyApp(
ui = shinyUI(fluidPage(
titlePanel("Test Shiny"),
sidebarLayout(
sidebarPanel(
checkboxGroupInput("fun", label = "Function",
choices = list("function1: x^2" = 1,
"function2: x^2 + x" = 2,
"function3: x^2 - x" = 3),
selected = c(1)),
h5("A single checkbox"),
checkboxInput("relation4", label = "relation4", value = FALSE)
),
mainPanel(
plotOutput("plot")
)
)
)),
server = shinyServer(function(input, output) {
x <- seq(0, 10, by=0.1)
fn1.geom <- reactive({
print("we are in fn1.geom <- reactive({})")
geom_line(mapping = aes(x, y=x^2), color="blue")
})
fn1 <- reactive({
print("we are in fn1 <- reactive({})")
if (1 %in% input$fun ) {
fn1.geom()}
})
fn2.geom <- reactive({
print("we are in fn2.geom <- reactive({})")
geom_line(mapping = aes(x, y=x^2 + x), color="red")
})
fn2 <- reactive({
print("we are in fn2 <- reactive({})")
if (2 %in% input$fun) {
fn2.geom()}
})
fn3.geom <- reactive({
print("we are in fn3.geom <- reactive({})")
geom_line(mapping = aes(x, y=x^2 - x), color="green")
})
fn3 <- reactive({
print("we are in fn3 <- reactive({})")
if (3 %in% input$fun) {
fn3.geom() }
})
# using single checkbox input (checkboxInput() above)
relation4.geom <- reactive({
print("we are in relation4.geom <- reactive({})")
list( geom_line(mapping = aes(x, y=x), color="orange"),
geom_line(mapping = aes(x, y=6*x), color="purple"),
geom_line(mapping = aes(x, y=11*x), color="violet") )
})
relation4 <- reactive({
print("we are in relation4 <- reactive({})")
if (input$relation4) {
relation4.geom()
}
})
output$plot <- renderPlot({
cat("\n we are in output$plot <- renderPlot({}) \n")
ggplot() + fn1() + fn2() + fn3() + relation4()
})
})
))