How a Macro Model Works
Models: inputs and outputs
A model is a rule that turns exogenous variables (fed in from outside) into endogenous variables (solved inside).
- Endogenous = determined by the model — here, the equilibrium price \(P\) and quantity \(Q\).
- Exogenous = taken as given — here, buyers’ income and the input price.
- Comparative statics = how the solution moves when an exogenous variable changes.
Supply, demand, equilibrium
- Demand slopes down: \(Q^d = 60 - 10P + 2\cdot\text{Income}\). Higher income shifts it right.
- Supply slopes up: \(Q^s = 8P - 2\cdot\text{Input price}\). A costlier input shifts it left.
- Equilibrium: the price where \(Q^d = Q^s\) — the market clears.
#| standalone: true
#| viewerHeight: 520
library(shiny)
ui <- fluidPage(
tags$head(tags$style(HTML("body{font-family:'Inter',system-ui,sans-serif;}
.sb{background:#f0f4f8;border-radius:6px;padding:12px 14px;margin-top:10px;font-size:14px;line-height:1.8;} .sb b{color:#1f3b73;}"))),
sidebarLayout(
sidebarPanel(width=4,
sliderInput("inc","Buyers' income:",min=0,max=30,value=10,step=1),
sliderInput("pin","Input price:",min=0,max=20,value=5,step=1),
uiOutput("sb")),
mainPanel(width=8, plotOutput("plot",height="440px"))))
server <- function(input,output,session){
solve <- function(inc,pin){ P <- (60+2*inc+2*pin)/18; Q <- 8*P-2*pin; list(P=P,Q=Q) }
output$plot <- renderPlot({
e <- solve(input$inc,input$pin); b <- solve(10,5)
Pg <- seq(0,10,length.out=200); Qd <- 60-10*Pg+2*input$inc; Qs <- 8*Pg-2*input$pin
par(mar=c(4.2,4.4,1,1))
plot(NA,xlim=c(0,90),ylim=c(0,10),xlab="Quantity Q",ylab="Price P",las=1,bty="l",cex.lab=1.15)
points(b$Q,b$P,pch=1,col="#9aa4b2",cex=1.4,lwd=2)
lines(Qd,Pg,col="#1f3b73",lwd=3); lines(Qs,Pg,col="#b5462a",lwd=3)
points(e$Q,e$P,pch=19,col="#1c6b4a",cex=1.7)
segments(0,e$P,e$Q,e$P,lty=3,col="#5a6472"); segments(e$Q,0,e$Q,e$P,lty=3,col="#5a6472")
legend("topright",c("Demand","Supply","Equilibrium","Baseline"),col=c("#1f3b73","#b5462a","#1c6b4a","#9aa4b2"),
lwd=c(3,3,NA,NA),pch=c(NA,NA,19,1),bty="n")
})
output$sb <- renderUI({ e <- solve(input$inc,input$pin)
HTML(sprintf("<div class='sb'>Equilibrium price <b>P* = %.2f</b><br>Equilibrium quantity <b>Q* = %.1f</b></div>",e$P,e$Q)) })
}
shinyApp(ui,server)
What to notice
- Income up → demand shifts right → both P and Q rise.
- Input price up → supply shifts left → P rises, Q falls.
- The model can tell you how a shock moves P and Q — but not why income itself changed. That needs a bigger model.