如果我想绘制解决方案的另一部分,如何使 R Shiny 对滑块更改做出反应,但不重新计算所有内容



我是闪亮的新手(并且刚刚加入堆栈溢出,所以如果我还没有遵守所有礼仪规则,请道歉:)(,虽然我已经设法让我的代码工作,但有些事情我就是无法理解。下面是一个求解两个微分方程组的代码,使用闪亮滑块选择系数,在主面板中,我试图选择要绘制的两个变量中的哪一个。问题在于,由于绘图变量的选择是"输入"的一部分,如果我更改要绘制的变量,这会导致整个事情的重新计算。我以一个小系统为例附上了一个说明这个问题的简短代码,但实际上我有一个非常大的常微分方程系统,需要花费相当多的时间来解决,所以我真的需要确保如果带有参数的滑块没有改变,系统只解决一次, 然后我可以单独绘制每个变量,而无需对整个变量进行耗时的重新计算。

我已经查看了"响应式"作为一种选择,但看不到如何使其为此工作。您能否看看下面的短代码,让我知道这是否可能,更具体地说,如何使其绘制 U 或 V 但不再次解决系统。

提前非常感谢!

library(deSolve)
library(shiny)
library(shinyWidgets)
library(plotly)
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
fluidRow(
column(width=6,
sliderInput("a", "Coef 1",0, 5, 1, step=0.2),
sliderInput("b", "Coef 2", 0, 5, 1, step=0.2)
)
)
),
mainPanel(
selectInput("Var",
label = "Choose variable to plot:",
choices = c("First"="U", "Second"="V"), 
selected = c("U")
),
plotlyOutput("plot0")
)
)
)
LV=function(t,y,p){ # define Lotka-Volterra system
with(as.list(p),{
z=rep(0,2)
z[1]=y[1]-a*y[1]*y[2]
z[2]=b*y[1]*y[2]-y[2]
return(list(z))
})
}
Run_LV=function(p){ # run the simmulation
t = seq(from=0, to=10, by=0.1)
y0=c(1.5,0.7) # initial condition
para=c(list("a"=p$a,"b"=p$b)) # values of parameters
out = ode(y=y0, times=t, func=LV, parms=para ,method="ode45")
return(list("out"=out))
}
server <- function(input, output) {
output$plot0=renderPlot({
sim=Run_LV(input)
sol=sim$out
xvar=sol[,1] # time
if(input$Var=="U"){
yvar=sol[,2] # will plot U component
}else{
yvar=sol[,3] # will plot V component
}
data<- data.frame(xvar,yvar)
p=plot_ly(data,x=~xvar, y=~yvar, type = 'scatter', mode = 'lines')
p
})
}
shinyApp(ui = ui, server = server)

这是我作为 Markdown 文档实现的 Lotka-Volterra 教学应用程序之一。我希望它能作为一个例子:

---
title: "Resource Dependent Lotka Volterra Model"
output: html_document
runtime: shiny
---

```{r, echo=FALSE}
suppressMessages(library(deSolve))
lv <- function (t, x, parms) {
with(as.list(c(x, parms)),{
ds <- s_in - b * s * p + g * k + pulse(t, s_start, s_duration, s_pulse)
dp <- c * s * p - d * k * p
dk <- e * p * k - f * k
list(c(ds, dp, dk))
})
}
#parms  <- c(s_in=0, b=0, c=0.1, d=0.1, e=0.1, f=0.1, g=0, s_start=0, s_duration=0, s_pulse=0)
times  <- seq(0, 200, by=0.2)
#init   <- c(s=1, p=1, k=0.5)
pulse <- function(t, s_start, s_duration, h_pulse) {
if ((s_start <= t) & (t < (s_start + s_duration))) h_pulse else 0
} 
```

```{r, echo = FALSE, }
simulate <- reactive({
parms  <- c(s_in=input$s_in,
b=input$b, c=input$c, d=input$d, e=input$e, f=input$f, g=input$g,
s_start=input$s_start, s_duration=input$s_duration, s_pulse=input$s_pulse)
init <- c(s=input$S0, p=input$P0, k=input$K0)
ode(init, times, lv, parms, method="adams")
})
```

```{r, echo=FALSE}
renderPlot({
#print(system.time(
res <- simulate()
#))
par(lwd=2)
par(las=1)
par(cex.axis=1.4)
layout(matrix(c(1,2), nrow=1, byrow=TRUE), widths=c(2, 1))
matplot(res[,1], res[,2:4], type="l", xlab="time", col=c("black", "forestgreen", "red"), lwd=3, ylab="state variables")
legend("topright", legend=c("S", "P", "K"), col=c("black", "forestgreen", "red"), lwd=3, lty=1:3, cex=1.4)
plot(res[,3], res[,4], type="l", xlab="P", ylab="K")
})
```
<small>
```{r, echo=FALSE}
inputPanel(flowLayout(
h4("Initial values:"),
numericInput(
"S0", label = "S0: Substrate", value = 1.0, min = 0, max = 2, step = 0.1
),
numericInput(
"P0", label = "P0: Producer", value = 1.0, min = 0, max = 2, step = 0.1
),
numericInput(
"K0", label = "K0: Consumer", value = 0.5, min = 0, max = 2, step = 0.1
)),
flowLayout(
h4("Model parameters:"),
numericInput(
"b", label = "b: substrate utilisation", value = 0.0, min = 0, max = 1, step = 0.01
),
numericInput(
"c", label = "c: producer growth", value = 0.1, min = 0, max = 1, step = 0.1
),
numericInput(
"d", label = "d: predation loss", value = 0.1, min = 0, max = 1, step = 0.1
),
numericInput(
"e", label = "e: consumer growth", value = 0.1, min = 0, max = 1, step = 0.1
),
numericInput(
"f", label = "f: consumer mortality", value = 0.1, min = 0, max = 1, step = 0.1
),
numericInput(
"g", label = "g: substrate recycling", value = 0.0, min = 0, max = 1, step = 0.01
)),
flowLayout(
h4("Substrate import:"),
numericInput(
"s_in", label = "S_in (import baselevel)", value = 0.0, min = 0, max = 1, step = 0.01
),
sliderInput(
"s_pulse", label = "s_pulse (pulse height):", min = 0.0, max = 1.0, value = 0, step = 0.1
),
sliderInput(
"s_start", label = "s_start (time of pulse):",min = 0.0, max = max(times), value = 10, step = 1
),
sliderInput(
"s_duration", label = "s_duration (duration):", min = 0.0, max = 5, value = 1, step = 0.1
)
), textsize="50%")
```
</small>
### 3D State diagram
```{r, echo=FALSE}
library(scatterplot3d)
renderPlot({
res <- simulate()
scatterplot3d(res[,2], res[,3], res[,4], type="l", xlab="S", ylab="P", zlab="K", color="red", lwd=2)
}, width=600, height=400)
```

相关内容

最新更新