我的应用程序需要多个输入(一些是固定的,一些是由用户定义的),并使用长而复杂的反应代码生成多个输出。输出存储在列表中以方便参考。 输出中是输入之一(其所有可能值)与输出之一的关系图。因此,我需要停止对这一输入的反应才能生成绘图。但我想避免重复 renderPlot() 内的长代码。关于如何实现这一目标有什么想法吗?
下面给出了绘制 y1 与 x1 的示例图。它应该帮助用户了解 x1 的什么值会产生所需的 y1,其他参数固定。 我用重复编写的完整应用程序:https://katrine.shinyapps.io/salmoncycleupd1/
library(shiny)
library(bslib)
#fixed parameters
a<-10
b<-20
ui <- page_sidebar (
title = "updatable shiny1",
sidebar = sidebar(
sliderInput(
"Input1",
tags$strong("Define Input1"),
min = 1,
max = 15,
value = 5,
step = 1
),
sliderInput(
"Input2",
tags$strong("Define Input2"),
min = 100,
max = 1000,
value = 100,
step = 100
),
sliderInput(
"Input3",
tags$strong("Define Input3"),
min = 7,
max = 17,
value = 12
)
),
tabPanel(tags$h4("Outputs"),
layout_columns(
card(card_header(tags$span("Output1", style="color:tomato")),tableOutput("Output1")),
card(card_header(tags$span("Output2", style="color:tomato")),tableOutput("Output2")),
card(card_header(tags$span("Optimal", style="color:tomato")),plotOutput("Optimal")),
)
)
)
server <- function(input, output) {
mymodel <- reactive({
x1 <- input$Input1
x2 <- input$Input2
x3 <- input$Input3
#long and complex calculations
y1 <- x1+x2+x3
y2 <- x1*a
y3 <- x2*b
y4 <- x3+a+b
# Store all results in a list for use in different tables
list("y1" = y1, "y2" = y2, "y3" = y3, "y4" <- y4)
})
output$Output1 <- renderTable({
table1 <- data.frame(matrix(ncol = 2, nrow = 2))
colnames(table1) <- c("element1", "element2")
table1$element1 <- c(a, b)
table1$element2 <- c(mymodel()$y1, mymodel()$y2)
table1
})
output$Output2 <- renderTable({
table2 <- data.frame(matrix(ncol = 2, nrow = 2))
colnames(table2) <- c("element1", "element2")
table2$element1 <- c(a, b)
table2$element2 <- c(mymodel()$y3, mymodel()$y4)
table2
})
output$Optimal <- renderPlot({
#plot y1 against x1, when x2 and x3 are still reactive
#x1 is no longer reactive
x2 <- input$Input2
x3 <- input$Input3
optim <- function (x1) { # have to copy parts from mymodel here,
# cannot use y1 from the list as it is all reactive
y1 <- x1+x2+x3
}
y1_range <- c(optim(1), optim(2), optim(3), optim(4), optim(5), optim(6), optim(7),optim(8), optim(9), optim(10), optim(11), optim(12), optim(13), optim(14), optim(15))
x1_range <- c(1:15)
plot(x1_range,y1_range, type="l", xlab="x1, other parameters fixed", ylab= "y1", col="darkgreen", lwd=2)
})
}
shinyApp(ui = ui, server = server)
我研究过isolate()函数,但无法使其工作。
我尝试将函数与数据图中的反应数据分开。
注意两个错别字
"y4" = y4
(原为"y4" <- y4
)optim()
: y1 <- x1+x2+x3
在函数末尾不返回任何内容。options(shiny.reactlog=TRUE)
library(shiny)
library(bslib)
#fixed parameters
a<-10
b<-20
ui <- page_sidebar (
title = "updatable shiny1",
sidebar = sidebar(
sliderInput(
"Input1",
tags$strong("Define Input1"),
min = 1,
max = 15,
value = 5,
step = 1
),
sliderInput(
"Input2",
tags$strong("Define Input2"),
min = 100,
max = 1000,
value = 100,
step = 100
),
sliderInput(
"Input3",
tags$strong("Define Input3"),
min = 7,
max = 17,
value = 12
)
),
tabPanel(tags$h4("Outputs"),
layout_columns(
card(card_header(tags$span("Output1", style="color:tomato")),tableOutput("Output1")),
card(card_header(tags$span("Output2", style="color:tomato")),tableOutput("Output2")),
card(card_header(tags$span("Optimal", style="color:tomato")),plotOutput("Optimal")),
)
)
)
server <- function(input, output) {
MyComplexCalc <- function(x1 , x2, x3) {
#long and complex calculations
y1 <- x1+x2+x3
y2 <- x1*a
y3 <- x2*b
y4 <- x3+a+b
# Store all results in a list for use in different tables
list("y1" = y1, "y2" = y2, "y3" = y3, "y4" = y4,
"x1" = x1, "x2" = x2, "x3" = x3)
}
mymodel <- reactive({
MyComplexCalc(
x1 = input$Input1,
x2 = input$Input2,
x3 = input$Input3
)
})
output$Output1 <- renderTable({
table1 <- data.frame(matrix(ncol = 2, nrow = 2))
colnames(table1) <- c("element1", "element2")
table1$element1 <- c(a, b)
table1$element2 <- c(mymodel()$y1, mymodel()$y2)
table1
})
output$Output2 <- renderTable({
table2 <- data.frame(matrix(ncol = 2, nrow = 2))
colnames(table2) <- c("element1", "element2")
table2$element1 <- c(a, b)
table2$element2 <- c(mymodel()$y3, mymodel()$y4)
table2
})
y_DatasPlot <- reactive({
optim <- function (x1,datas) {
MyComplexCalc(
x1 = x1,
x2 = datas$x2,
x3 = datas$x3
)$y1
}
datas2 <- mymodel()
c(optim(1,datas2), optim(2,datas2), optim(3,datas2), optim(4,datas2), optim(5,datas2), optim(6,datas2),
optim(7,datas2),optim(8,datas2), optim(9,datas2), optim(10,datas2), optim(11,datas2), optim(12,datas2),
optim(13,datas2), optim(14,datas2), optim(15,datas2))
})
output$Optimal <- renderPlot({
y1_range <- y_DatasPlot()
x1_range <- c(1:15)
plot(x1_range,y1_range, type="l", xlab="x1, other parameters fixed", ylab= "y1", col="darkgreen", lwd=2)
})
}
shinyApp(ui = ui, server = server)
PS:您完整编写的应用程序具有非常干净的外观。