我想构建一个反应式 Rshiny 应用程序,它显示由 deSolve 包解决的动态模型的结果。
示例代码复制自 Jim Duggans System Dynamics Modeling with R。
这是没有 R-Shiny 的代码,它是一个考虑资源消耗的经济模型:
library(deSolve)
library(ggplot2)
library(gridExtra)
##Values Specification for Model
START <-0; FINISH<-200; STEP<-0.25
simtime <- seq(START, FINISH, by = STEP)
stocks <- c(sCapital=5, sResource=1000)
auxs <- c(aDesired.Growth = 0.07,
aDepreciation = 0.05,
aCost.Per.Investment = 2,
aFraction.Reinvested =0.12,
aRevenue.Per.Unit =3.00)
x.Resource <- seq(0,1000, by=100)
y.Efficiency<- c(0,0.25,0.45,0.63,0.75,0.86,0.92, 0.96,0.98, 0.99,1.0)
func.Efficiency <- approxfun(x=x.Resource,
y=y.Efficiency,
method = "linear",
yleft = 0, yright = 1.0)
#The Model
model <- function(time,stocks,auxs){
with(as.list(c(stocks,auxs)),{
aExtr.Efficiency <- func.Efficiency(sResource)
fExtraction <- aExtr.Efficiency*sCapital
aTotal.Revenue <- aRevenue.Per.Unit * fExtraction
aCapital.Costs <- sCapital *0.1
aProfit <- aTotal.Revenue - aCapital.Costs
aCapital.Funds <- aFraction.Reinvested * aProfit
aMaximum.Investment <- aCapital.Funds/aCost.Per.Investment
aDesired.Investment <- sCapital * aDesired.Growth
fInvestment <- min(aMaximum.Investment,
aDesired.Investment)
fDepreciation <- sCapital * aDepreciation
dS_dt <- fInvestment -fDepreciation
dR_dt <- -fExtraction
return(list(c(dS_dt, dR_dt),
DesiredInvestment=aDesired.Investment,
MaximumInvestment=aMaximum.Investment,
Investment=fInvestment,
Depreciation=fDepreciation,
Extraction=fExtraction))
})
}
### Using the deSolve Package to solve the differential equation
o <- data.frame(ode(y=stocks, times=simtime, func = model,
parms = auxs, method = "euler"))
##different Plots
flow_plot <- ggplot(data = o, mapping = aes(time, Investment)) + theme_classic() +
geom_line(data = o, mapping = aes(time, Investment), size = 1, color = "blue", linetype =2)+
geom_line(data = o, mapping = aes(time, Depreciation), size = 1, color = "red",linetype =2)+
geom_line(data = o, mapping = aes(time, Investment-Depreciation), size = 1, color = "black")
capital_plot <- ggplot(data = o, mapping = aes(time, sCapital)) + theme_classic() +
geom_line(data = o, mapping = aes(time, sCapital), size = 1, color = "blue", linetype =2)+
geom_line(data = o, mapping = aes(time, Extraction), size = 1, color = "black")
ressource_plot <- ggplot(data = o, mapping = aes(time, sCapital)) + theme_classic() +
geom_line(data = o, mapping = aes(time, sResource), size = 1, color = "black", linetype =1)
grid.arrange(flow_plot,capital_plot,ressource_plot, nrow = 3)
R-Shiny React 部分
现在我尝试将所有这些包装到一个非常基本的 R-Shiny 应用程序中,代码如下:
library(shiny)
library(deSolve)
library(ggplot2)
library(gridExtra)
ui <- fluidPage(
sliderInput("iDesired.Growth", "Desired.Growth", min = 0, max = 0.15, step = 0.01, value = 0.07),
sliderInput("iDepreciation", "Depreciation", min = 0, max = 0.15, step = 0.01, value = 0.07),
plotOutput(outputId = "arrange")
)
server <- function(input, output, session) {
START <-0; FINISH<-200; STEP<-0.25
simtime <- seq(START, FINISH, by = STEP)
stocks <- c(sCapital=5, sResource=1000)
auxs <- list(aDesired.Growth = reactiveVal(input$iDesired.Growth),
aDepreciation = reactiveVal(input$iDepreciation),
aCost.Per.Investment = 2,
aFraction.Reinvested =0.12,
aRevenue.Per.Unit =3.00)
x.Resource <- seq(0,1000, by=100)
y.Efficiency<- c(0,0.25,0.45,0.63,0.75,0.86,0.92, 0.96,0.98, 0.99,1.0)
func.Efficiency <- approxfun(x=x.Resource,
y=y.Efficiency,
method = "linear",
yleft = 0, yright = 1.0)
model <- function(time,stocks,auxs){
with(as.list(c(stocks,auxs)),{
aExtr.Efficiency <- func.Efficiency(sResource)
fExtraction <- aExtr.Efficiency*sCapital
aTotal.Revenue <- aRevenue.Per.Unit * fExtraction
aCapital.Costs <- sCapital *0.1
aProfit <- aTotal.Revenue - aCapital.Costs
aCapital.Funds <- aFraction.Reinvested * aProfit
aMaximum.Investment <- aCapital.Funds/aCost.Per.Investment
aDesired.Investment <- sCapital * aDesired.Growth
fInvestment <- min(aMaximum.Investment,
aDesired.Investment)
fDepreciation <- sCapital * aDepreciation
dS_dt <- fInvestment -fDepreciation
dR_dt <- -fExtraction
return(list(c(dS_dt, dR_dt),
DesiredInvestment=aDesired.Investment,
MaximumInvestment=aMaximum.Investment,
Investment=fInvestment,
Depreciation=fDepreciation,
Extraction=fExtraction))
})
}
o <- data.frame(ode(y=stocks, times=simtime, func = model,
parms = auxs, method = "euler"))
flow_plot <- ggplot(data = o, mapping = aes(time, Investment)) + theme_classic() +
geom_line(data = o, mapping = aes(time, Investment), size = 1, color = "blue", linetype =2)+
geom_line(data = o, mapping = aes(time, Depreciation), size = 1, color = "red",linetype =2)+
geom_line(data = o, mapping = aes(time, Investment-Depreciation), size = 1, color = "black")
f <- renderPlot({
flow_plot <- ggplot(data = o, mapping = aes(time, Investment)) + theme_classic() +
geom_line(data = o, mapping = aes(time, Investment), size = 1, color = "blue", linetype =2)+
geom_line(data = o, mapping = aes(time, Depreciation), size = 1, color = "red",linetype =2)+
geom_line(data = o, mapping = aes(time, Investment-Depreciation), size = 1, color = "black")
})
capital_plot <- ggplot(data = o, mapping = aes(time, sCapital)) + theme_classic() +
geom_line(data = o, mapping = aes(time, sCapital), size = 1, color = "blue", linetype =2)+
geom_line(data = o, mapping = aes(time, Extraction), size = 1, color = "black")
ressource_plot <- ggplot(data = o, mapping = aes(time, sCapital)) + theme_classic() +
geom_line(data = o, mapping = aes(time, sResource), size = 1, color = "black", linetype =1)
output$arrange <- renderPlot({
grid.arrange(flow_plot,capital_plot,ressource_plot, nrow = 3)
})
}
shinyApp(ui, server)
现在我很确定问题出在 auxs 变量的类型上:
auxs <- list(aDesired.Growth = reactiveVal(input$iDesired.Growth),
aDepreciation = reactiveVal(input$iDepreciation),
aCost.Per.Investment = 2,
aFraction.Reinvested =0.12,
aRevenue.Per.Unit =3.00)
你知道我是否可以在不改变函数的情况下实现反应性:模型或我必须做出反应性的函数/变量以及如何?
提前非常感谢。