Um Märkte zu verstehen, brauchen wir eine Vorstellung der Nachfrage
Zusammen mit dem Angebot bestimmt sie Preise und Konsum
Sie sagt uns, wer wie viel konsumiert und somit wie es um die Konsumentenwohlfahrt
steht
Marktnachfrage wird (heutzutage) immer auf individuelle Nachfragen, also auf das Entscheidungsverhalten von einzelnen Konsument zurückgeführt.
In der Einführungsvorlesung haben wir uns Ihre Nachfrage nach Smartphones angesehen. Wovon hängt sie ab?
Ihr Bedarf bzw. Ihre Wünsche
Ihr (knappes) Budget und der Preis
Ob Sie beides gut in Einklang bringen können
In der VWL haben wir dafür spezielle Namen, aber die Interpretation ist gleich
Präferenzen
Budget
Ob Sie rational und insbesondere nutzenmaximierend
handeln
Ziele
Verstehen, wie Ökonomen über Präferenzen und Budgets nachdenken
Analysieren, wie optimale Nachfrageentscheidungen und eine Marktnachfrage zustande kommen
Nützliche Konzepte entwickeln und verstehen, die uns auch später helfen werden
Ressourcen
(Einige) Kapitel im Varian: 2 - 8, 14, 15
Interaktive Diagramme
Betrachten wir 2 Güter
– ohne Beschränkung der Allgemeinheit
Ein Güterbündel
ist \(\boldsymbol{x} \equiv (x_1,x_2)\), wobei \(x_i\geq 0\) die konsumierte Menge
darstellt
Die dazugehörigen Preise
\(p_i\) pro Einheit sind für Konsumenten gegeben
und einheitlich
Das verfügbare Budget
ist \(m\)
Die Budgetmenge
enthält alle Güterbündel, die bei den aktuellen Preisen erschwinglich sind \[
\boldsymbol{x}'\boldsymbol{p} = p_1 x_1 + p_2 x_2 \leq m
\]
Sie wird durch die Budgetgerade
abgegrenzt, also die Menge aller Güterbündel, die das Budget vollkommen erschöpfen
\[ x_2 = \frac{m}{p_2}-\frac{p_1}{p_2}x_1 \]
Die Steigung zeigt an, mit welcher Rate die beiden Güter auf der Budgetgerade füreinander substituiert werden können, also die Opportunitätskosten
Opportunitätskosten
Opportunitätskosten sind allgemein die ökonomischen Kosten einer Entscheidung, also der Wert der nächstbesten ungenutzten Alternative. Im Kontext der Budgetgeraden entsprechen diese der Steigung:
\[ \frac{\mathrm{d}x_2}{\mathrm{d}x_1} = -\frac{p_1}{p_2} \]
Opportunitätskosten sind vielleicht das wichtigste Konzept in den Wirtschaftswissenschaften (und darüber hinaus)
Einige Beispiele:
Studieren und insbesondere ein Doktorat haben hohe Opportunitätskosten: entgangenes Einkommen und Erfahrung
Jede Ausgabe – zum Beispiel eine Investition – hat Opportunitätskosten in Höhe des “Zinses”, den das Geld angelegt erwirtschaftet hätte
DIY (z.B. Heimwerkeln) ist immer eine Abwägung, da die eigene Zeit auch anders genutzt werden kann
Forschung vs Administration und Spezialisierung nach komparativem Vorteil
Aber kehren wir zurück zur Budgetbeschränkung…
#| standalone: true
#| viewerHeight: 600
library(shiny)
options(shiny.mathjax.url = "https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.7/MathJax.js")
library(ggplot2)
# Define UI
ui <- fluidPage(
br(),
withMathJax(),
sidebarLayout(
sidebarPanel(
h3("Nutzenmaximierung"),
tabsetPanel(
tabPanel("Hauptmenü", width = "400px",
br(),
p("\\(\\alpha\\) ist der Hauptparameter für die Nutzenfunktion. Unter \"Erweitert\" finden Sie weitere Optionen und können Budgetbeschränkungen umschalten."),
sliderInput(inputId = "alpha",
label = "Wähle \\(\\alpha\\)",
min = 0.01,
max = 0.99,
value = 0.5,
step = 0.01),
selectInput("utilityType",
"Wähle Nutzenfunktion:",
choices = c("Cobb-Douglas" = "cd",
"Perfekte Substitute" = "ps",
"Perfekte Komplemente" = "pc"
# ,
# "CES" = "ces"
)),
uiOutput('formula'),
checkboxInput("showBudgetLine",
"Zeige Budgetbeschränkung",
value = FALSE),
checkboxInput("showIndifferenceCurve",
"Zeige Indifferenzkurven",
value = FALSE)
),
tabPanel("Erweitert",
br(),
sliderInput("Px",
"Preis von Gut 1",
min = 1,
max = 5,
value = 4,
step = 0.1),
sliderInput("Py",
"Preis von Gut 2",
min = 1,
max = 5,
value = 2,
step = 0.1),
sliderInput("budget",
"Budget",
min = 100,
max = 300,
value = 200,
step = 1),
br(),
actionButton("reset", "Reset")
)
)
),
mainPanel(
align="center",
plotOutput(outputId = "utilityPlot", height = "550px", width = "600px"),
)
)
)
# Define server logic
server <- function(input, output) {
# Define utility functions
utility_function <- function(alpha, x, y, type) {
if (type == "cd") {
return(x^alpha * y^(1 - alpha))
}
if (type == "ps") {
return(alpha*x + (1-alpha)*y)
}
if (type == "pc") {
return(pmin(alpha*x, y))
}
# if (type == "ces") {
# rho = 0.5
# return((alpha*x^rho + (1-alpha)*y^rho)^(1/rho))
# }
}
# Find maximal utility
maximizeUtility <- function(budget, Px, Py, alpha, type) {
if (type == "cd") {
quantity_x <- (alpha * budget) / Px
quantity_y <- ((1 - alpha) * budget) / Py
max_utility <- utility_function(alpha, quantity_x, quantity_y, "cd")
} else if (type == "ps") {
utility_per_dollar_x <- alpha / Px
utility_per_dollar_y <- (1 - alpha) / Py
if (utility_per_dollar_x > utility_per_dollar_y) {
quantity_x <- budget / Px
quantity_y <- 0
} else {
quantity_x <- 0
quantity_y <- budget / Py
}
max_utility <- utility_function(alpha, quantity_x, quantity_y, "ps")
} else if (type == "pc") {
quantity_x <- budget / (Px + alpha * Py)
quantity_y <- alpha * (budget / (Px + alpha * Py))
max_utility <- utility_function(alpha, quantity_x, quantity_y, "pc")
}
# else if (type == "ces") {
# objective_function <- function(x) {
# y <- (budget - Px*x) / Py
# utility_function(alpha, x, y, "ces")
# }
# lower_bound <- 0
# upper_bound <- budget / Px
# optimization_result <- optimize(objective_function, interval = c(lower_bound, upper_bound), maximum = TRUE)
# quantity_x <- optimization_result$maximum
# quantity_y <- (budget - Px*quantity_x) / Py
# max_utility <- optimization_result$objective
# }
else {
stop("Unknown utility function type.")
}
return(list(max_utility = max_utility, quantity_x = quantity_x, quantity_y = quantity_y))
}
output$utilityPlot <- renderPlot({
alpha <- input$alpha
Px <- input$Px
Py <- input$Py
budget <- input$budget
type <- input$utilityType
showBudgetLine <- input$showBudgetLine
showIndifferenceCurve <- input$showIndifferenceCurve
maxutil_all <- maximizeUtility(budget, Px, Py, alpha, type)
maxutil <- maxutil_all$max_utility
quantity_x <- maxutil_all$quantity_x
quantity_y <- maxutil_all$quantity_y
x <- c(seq(1, 100, by = 2), seq(round(quantity_x*0.75, 1), round(quantity_x*1.25, 1), by = .1))
y <- c(seq(1, 100, by = 2), seq(round(quantity_y*0.75, 1), round(quantity_y*1.25, 1), by = .1))
grid <- expand.grid(x = x, y = y)
grid$utility <- utility_function(alpha, grid$x, grid$y, type)
if(showIndifferenceCurve) {
plot <- ggplot(grid, aes(x = x, y = y)) +
geom_contour(aes(z = utility), breaks = c(maxutil), color = "red") +
geom_contour(aes(z = utility), breaks = c(maxutil*0.8, maxutil*1.2), color = "red", linetype = "dashed") +
coord_cartesian(xlim = c(0, 100), ylim = c(0, 100)) +
theme_minimal()+
labs(x = expression(x[1]), y = expression(x[2])) +
theme(
axis.title.x = element_text(size = 20), # Adjust the font size of x-axis label
axis.title.y = element_text(size = 20) # Adjust the font size of y-axis label
)
} else if(showBudgetLine){
plot <- ggplot(grid, aes(x = x, y = y)) +
geom_abline(intercept = budget/Py, slope = -Px/Py, color = "blue") +
geom_blank() +
coord_cartesian(xlim = c(0, 100), ylim = c(0, 100)) +
theme_minimal()+
labs(x = expression(x[1]), y = expression(x[2])) +
theme(
axis.title.x = element_text(size = 20), # Adjust the font size of x-axis label
axis.title.y = element_text(size = 20) # Adjust the font size of y-axis label
)
} else {
plot <- ggplot(grid, aes(x = x, y = y)) +
coord_cartesian(xlim = c(0, 100), ylim = c(0, 100)) +
theme_minimal()+
labs(x = expression(x[1]), y = expression(x[2])) +
theme(
axis.title.x = element_text(size = 20), # Adjust the font size of x-axis label
axis.title.y = element_text(size = 20) # Adjust the font size of y-axis label
)
}
if(showBudgetLine && showIndifferenceCurve){
plot <- plot + geom_abline(intercept = budget/Py, slope = -Px/Py, color = "blue")+
annotate("segment", x = quantity_x, xend = quantity_x, y = 0, yend = quantity_y, linetype = "dashed")+
annotate("segment", x = 0, xend = quantity_x, y = quantity_y, yend = quantity_y, linetype = "dashed")+
annotate("label", x = quantity_x, y = 0, label = round(quantity_x, 2))+
annotate("label", x = 0, y = quantity_y, label = round(quantity_y, 2))+
geom_contour(aes(z = utility), breaks = c(maxutil), color = "red") +
geom_contour(aes(z = utility), breaks = c(maxutil*0.8, maxutil*1.2), color = "red", linetype = "dashed") +
coord_cartesian(xlim = c(0, 100), ylim = c(0, 100)) +
theme_minimal()+
labs(x = expression(x[1]), y = expression(x[2])) +
theme(
axis.title.x = element_text(size = 20), # Adjust the font size of x-axis label
axis.title.y = element_text(size = 20) # Adjust the font size of y-axis label
)
}
plot
})
observeEvent(input$reset, {
updateSliderInput(inputId = "alpha", value = 0.5)
updateCheckboxInput(inputId = "showBudgetLine", value = FALSE)
updateCheckboxInput(inputId = "showIndifferenceCurve", value = FALSE)
updateSliderInput(inputId = "Px", value = 4)
updateSliderInput(inputId = "Py", value = 2)
updateSliderInput(inputId = "budget", value = 200)
})
output$formula <- renderUI({
formula <- switch(input$utilityType,
"cd" = "$$U(x_1, x_2) = x_1^{\\alpha} x_2^{1-\\alpha}$$",
"ps" = "$$U(x_1, x_2) = \\alpha x_1 + (1-\\alpha) x_2$$",
"pc" = "$$U(x_1, x_2) = \\min(\\alpha x_1, x_2)$$",
#"ces" = "$$U(x, y) = (\\alpha x^{\\rho} + (1-\\alpha) y^{\\rho})^{\\frac{1}{\\rho}}$$",
"")
withMathJax("Formel: ", formula)
})
}
# Run the application
shinyApp(ui = ui, server = server)
In der VWL modellieren wir Bedürfnisse und Wünsche mithilfe von Präferenzen
bevorzugen strikt
Apple; dann schreiben wir \[
(1,0) \succ (0,1)
\]indifferent
\[
(1,0) \sim (0,2)
\]schwache Präferenz
für das iPhone \[
(1,0) \succsim (0,1)
\]Alle Operatoren zeigen Präferenzrelationen
– diese werden uns sehr helfen, wenn wir die Nachfrage finden wollen
Wir nehmen für unsere Konsumenten zumeist an, dass ihre Präferenzen bestimmte Eigenschaften erfüllen, sodass sie “wohlverhalten” sind (man also mit ihnen gut arbeiten kann):
vollständig \[ \boldsymbol{x} \succsim \boldsymbol{y} \ \ \lor \ \ \boldsymbol{y} \succsim \boldsymbol{x} \ \ \ \ \forall \ \boldsymbol{x}, \boldsymbol{y} \]
reflexiv \[ \boldsymbol{x} \succsim \boldsymbol{x} \ \ \ \ \forall \ \boldsymbol{x} \]
transitiv (das \(\land\) steht für das logische “Und”) \[ \boldsymbol{x} \succsim \boldsymbol{y} \ \ \land \ \ \boldsymbol{y} \succsim \boldsymbol{z} \ \ \implies \ \boldsymbol{x} \succsim \boldsymbol{z} \ \ \ \ \forall \ \boldsymbol{x}, \boldsymbol{y}, \boldsymbol{z} \]
monoton \(\leftrightarrow\) keine Sättigung \[ x_i \geq y_i \ \ \ \ \forall \ i \ \ \implies \ \ \boldsymbol{x} \succsim \boldsymbol{y} \]
stetig
Teamarbeit: wie realitätsfern sind diese Annahmen?
Optimale Entscheidungen nur mithilfe von Präferenzrelationen zu finden ist schwierig…
Können wir vielleicht jedem Bündel einen Wert zuweisen, sodass die Präferenzen repräsentiert
werden?
Mit unseren Annahmen ist dies garantiert!
Wir haben dann sogar wohlverhaltene Funktionen
Diese Nutzenfunktionen
werden zumeist als \(u(\boldsymbol{x}) = u(x_1,x_2)\) notiert
Teamarbeit: Gehen Sie zurück auf Folie 13 und finden Sie Funktionen, die die jeweiligen Präferenzen repräsentieren könnten!
Sie haben sicher festgestellt: die gleichen Präferenzen können durch unendlich viele Funktionen dargestellt werden
Nutzenfunktionen sind also immer ordinal
: Sie geben nur Reihenfolgen an und absolute (kardindale
) Unterschiede im Nutzenwert haben keine Bedeutung
Somit können wir immer monotone Transformationen auf Nutzenfunktionen anwenden und die resultierende Funktion repräsentiert die selben Präferenzen!
Das steht in großen Kontrast zur Volkswirtschaftslehre in den Anfängen: im 18. Jahrhundert war “Nutzen” messbar und absolut…
\[ u(\boldsymbol{x}) = x_1 + x_2 \]
\[ u(\boldsymbol{x}) = \mathrm{min}\{x_1,x_2\} \]
\[ u(\boldsymbol{x}) = x_1^{\alpha}x_2^{1-\alpha} \ \ \ \ \text{with} \ \alpha \in (0,1) \]
\[ u(\boldsymbol{x}) = v(x_1) + x_2, \ \ \ \ \ \text{mit} \ \ \ \ v'>0, \ \ v''<0 \]
Teamarbeit: Beschreiben Sie das Verhalten dieser Präferenzen in Worten!
In diesem Teil lernen wir zwei nützliche Konzepte kennen, die uns helfen werden, Nutzenfunktionen besser zu verstehen und später die Nachfrage herzuleiten.
Grenznutzen
Indifferenzkurven
Auch wenn beide Konzepte zunächst formalistisch anmuten, können wir sie mithilfe von Beispielen leicht verstehen.
Grenznutzen ist positiv, aber abnehmend!
Indifferenzkurven geben an, in welchen Verhältnissen Güter konsumiert werden können, ohne dass sich das Nutzenniveau ändert.
Betrachten wir den Fall eines einzigen Gutes, sodass der Nutzen \(u=u(x)\) ist
Wie finden wir das beste Güterbündel ohne Budgetrestriktion?
Starten wir bei eine beliebigen Konsummenge \(x=k\). Wollen wir mehr oder weniger konsumieren?
Wenn der zusätzliche
Nutzen der nächsten Einheit größer als der Preis (gemessen in Nutzen) ist, wollen wir mehr! Wenn er niedriger ist, wollen wir den Konsum reduzieren.
Grenznutzen
Der Grenznutzen eines Gutes \(i\) (Marginal Utility), \[ \frac{\partial u(\boldsymbol{x})}{\partial x_i} \equiv MU_i(\boldsymbol{x}), \] ist der marginale Zusatznutzen, wenn man die Menge um eine infinitesimale Einheit erhöht.
Hinweise:
Typischerweise fällt der Grenznutzen eines Gutes, wenn man mehr konsumiert
Mit mehreren Gütern ist es komplizierter, aber der Grenznutzen wird dennoch eine zentrale Rolle spielen
Um das beste Güterbündel – und auch die Nachfrage – zu finden, werden wir ein sehr nützliches Konzept nutzen: Indifferenzkurven
\[ \{\boldsymbol{x}|u(\boldsymbol{x})=\bar{u}\} \]
substitutieren
, also freiwillig von einem Gut weniger und von anderen mehr konsumieren würden#| standalone: true
#| viewerHeight: 600
library(shiny)
options(shiny.mathjax.url = "https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.7/MathJax.js")
library(ggplot2)
# Define UI
ui <- fluidPage(
br(),
withMathJax(),
sidebarLayout(
sidebarPanel(
h3("Nutzenmaximierung"),
tabsetPanel(
tabPanel("Hauptmenü", width = "400px",
br(),
p("\\(\\alpha\\) ist der Hauptparameter für die Nutzenfunktion. Unter \"Erweitert\" finden Sie weitere Optionen und können Budgetbeschränkungen umschalten."),
sliderInput(inputId = "alpha",
label = "Wähle \\(\\alpha\\)",
min = 0.01,
max = 0.99,
value = 0.5,
step = 0.01),
selectInput("utilityType",
"Wähle Nutzenfunktion:",
choices = c("Cobb-Douglas" = "cd",
"Perfekte Substitute" = "ps",
"Perfekte Komplemente" = "pc"
# ,
# "CES" = "ces"
)),
uiOutput('formula'),
checkboxInput("showBudgetLine",
"Zeige Budgetbeschränkung",
value = FALSE),
checkboxInput("showIndifferenceCurve",
"Zeige Indifferenzkurven",
value = FALSE)
),
tabPanel("Erweitert",
br(),
sliderInput("Px",
"Preis von Gut 1",
min = 1,
max = 5,
value = 4,
step = 0.1),
sliderInput("Py",
"Preis von Gut 2",
min = 1,
max = 5,
value = 2,
step = 0.1),
sliderInput("budget",
"Budget",
min = 100,
max = 300,
value = 200,
step = 1),
br(),
actionButton("reset", "Reset")
)
)
),
mainPanel(
align="center",
plotOutput(outputId = "utilityPlot", height = "550px", width = "600px"),
)
)
)
# Define server logic
server <- function(input, output) {
# Define utility functions
utility_function <- function(alpha, x, y, type) {
if (type == "cd") {
return(x^alpha * y^(1 - alpha))
}
if (type == "ps") {
return(alpha*x + (1-alpha)*y)
}
if (type == "pc") {
return(pmin(alpha*x, y))
}
# if (type == "ces") {
# rho = 0.5
# return((alpha*x^rho + (1-alpha)*y^rho)^(1/rho))
# }
}
# Find maximal utility
maximizeUtility <- function(budget, Px, Py, alpha, type) {
if (type == "cd") {
quantity_x <- (alpha * budget) / Px
quantity_y <- ((1 - alpha) * budget) / Py
max_utility <- utility_function(alpha, quantity_x, quantity_y, "cd")
} else if (type == "ps") {
utility_per_dollar_x <- alpha / Px
utility_per_dollar_y <- (1 - alpha) / Py
if (utility_per_dollar_x > utility_per_dollar_y) {
quantity_x <- budget / Px
quantity_y <- 0
} else {
quantity_x <- 0
quantity_y <- budget / Py
}
max_utility <- utility_function(alpha, quantity_x, quantity_y, "ps")
} else if (type == "pc") {
quantity_x <- budget / (Px + alpha * Py)
quantity_y <- alpha * (budget / (Px + alpha * Py))
max_utility <- utility_function(alpha, quantity_x, quantity_y, "pc")
}
# else if (type == "ces") {
# objective_function <- function(x) {
# y <- (budget - Px*x) / Py
# utility_function(alpha, x, y, "ces")
# }
# lower_bound <- 0
# upper_bound <- budget / Px
# optimization_result <- optimize(objective_function, interval = c(lower_bound, upper_bound), maximum = TRUE)
# quantity_x <- optimization_result$maximum
# quantity_y <- (budget - Px*quantity_x) / Py
# max_utility <- optimization_result$objective
# }
else {
stop("Unknown utility function type.")
}
return(list(max_utility = max_utility, quantity_x = quantity_x, quantity_y = quantity_y))
}
output$utilityPlot <- renderPlot({
alpha <- input$alpha
Px <- input$Px
Py <- input$Py
budget <- input$budget
type <- input$utilityType
showBudgetLine <- input$showBudgetLine
showIndifferenceCurve <- input$showIndifferenceCurve
maxutil_all <- maximizeUtility(budget, Px, Py, alpha, type)
maxutil <- maxutil_all$max_utility
quantity_x <- maxutil_all$quantity_x
quantity_y <- maxutil_all$quantity_y
x <- c(seq(1, 100, by = 2), seq(round(quantity_x*0.75, 1), round(quantity_x*1.25, 1), by = .1))
y <- c(seq(1, 100, by = 2), seq(round(quantity_y*0.75, 1), round(quantity_y*1.25, 1), by = .1))
grid <- expand.grid(x = x, y = y)
grid$utility <- utility_function(alpha, grid$x, grid$y, type)
if(showIndifferenceCurve) {
plot <- ggplot(grid, aes(x = x, y = y)) +
geom_contour(aes(z = utility), breaks = c(maxutil), color = "red") +
geom_contour(aes(z = utility), breaks = c(maxutil*0.8, maxutil*1.2), color = "red", linetype = "dashed") +
coord_cartesian(xlim = c(0, 100), ylim = c(0, 100)) +
theme_minimal()+
labs(x = expression(x[1]), y = expression(x[2])) +
theme(
axis.title.x = element_text(size = 20), # Adjust the font size of x-axis label
axis.title.y = element_text(size = 20) # Adjust the font size of y-axis label
)
} else if(showBudgetLine){
plot <- ggplot(grid, aes(x = x, y = y)) +
geom_abline(intercept = budget/Py, slope = -Px/Py, color = "blue") +
geom_blank() +
coord_cartesian(xlim = c(0, 100), ylim = c(0, 100)) +
theme_minimal()+
labs(x = expression(x[1]), y = expression(x[2])) +
theme(
axis.title.x = element_text(size = 20), # Adjust the font size of x-axis label
axis.title.y = element_text(size = 20) # Adjust the font size of y-axis label
)
} else {
plot <- ggplot(grid, aes(x = x, y = y)) +
coord_cartesian(xlim = c(0, 100), ylim = c(0, 100)) +
theme_minimal()+
labs(x = expression(x[1]), y = expression(x[2])) +
theme(
axis.title.x = element_text(size = 20), # Adjust the font size of x-axis label
axis.title.y = element_text(size = 20) # Adjust the font size of y-axis label
)
}
if(showBudgetLine && showIndifferenceCurve){
plot <- plot + geom_abline(intercept = budget/Py, slope = -Px/Py, color = "blue")+
annotate("segment", x = quantity_x, xend = quantity_x, y = 0, yend = quantity_y, linetype = "dashed")+
annotate("segment", x = 0, xend = quantity_x, y = quantity_y, yend = quantity_y, linetype = "dashed")+
annotate("label", x = quantity_x, y = 0, label = round(quantity_x, 2))+
annotate("label", x = 0, y = quantity_y, label = round(quantity_y, 2))+
geom_contour(aes(z = utility), breaks = c(maxutil), color = "red") +
geom_contour(aes(z = utility), breaks = c(maxutil*0.8, maxutil*1.2), color = "red", linetype = "dashed") +
coord_cartesian(xlim = c(0, 100), ylim = c(0, 100)) +
theme_minimal()+
labs(x = expression(x[1]), y = expression(x[2])) +
theme(
axis.title.x = element_text(size = 20), # Adjust the font size of x-axis label
axis.title.y = element_text(size = 20) # Adjust the font size of y-axis label
)
}
plot
})
observeEvent(input$reset, {
updateSliderInput(inputId = "alpha", value = 0.5)
updateCheckboxInput(inputId = "showBudgetLine", value = FALSE)
updateCheckboxInput(inputId = "showIndifferenceCurve", value = FALSE)
updateSliderInput(inputId = "Px", value = 4)
updateSliderInput(inputId = "Py", value = 2)
updateSliderInput(inputId = "budget", value = 200)
})
output$formula <- renderUI({
formula <- switch(input$utilityType,
"cd" = "$$U(x_1, x_2) = x_1^{\\alpha} x_2^{1-\\alpha}$$",
"ps" = "$$U(x_1, x_2) = \\alpha x_1 + (1-\\alpha) x_2$$",
"pc" = "$$U(x_1, x_2) = \\min(\\alpha x_1, x_2)$$",
#"ces" = "$$U(x, y) = (\\alpha x^{\\rho} + (1-\\alpha) y^{\\rho})^{\\frac{1}{\\rho}}$$",
"")
withMathJax("Formel: ", formula)
})
}
# Run the application
shinyApp(ui = ui, server = server)
Um das beste Güterbündel – also die Nachfrage – zu finden, wollen wir die höchste Indifferenzkurve finden, auf der mind. ein Güterbündel in der Budgetmenge liegt
Die Steigung der Indifferenzkurve wird als Grenzrate der Substitution
bezeichnet (Marginal Rate of Substitution)
\[
\mathrm{d} u(x_1,x_2) = \mathrm{d} k = 0 = \frac{\partial u}{\partial x_1} \mathrm{d} x_1 + \frac{\partial u}{\partial x_2} \mathrm{d} x_2 \Leftrightarrow
\]
\[ \frac{\mathrm{d} x_2}{\mathrm{d} x_1} = \underbrace{- \frac{\frac{\partial u}{\partial x_1}}{\frac{\partial u}{\partial x_2}}}_{\text{Grenzrate der Substitution}} \equiv - \frac{MU_1}{MU_2} \equiv MRS_{1,2} \]
Die MRS ist bei differenzierbaren Nutzenfunktionen negativ
Sie gibt den “Wechselkurs” an, zu der Konsument:innen bereit sind, Güter füreinander auszutauschen
Bei schwach konvexen Präferenzen fällt die MRS nicht; bei strikt konvexen Präferenzen steigt sie
D.h. \(|MRS|\) nimmt typischerweise schwach ab
Man muss also immer mehr von einem Gut aufgeben, um den Nutzen durch Konsum des anderen Gutes konstant zu halten
In diesem Teil leiten wir uns die individuelle Nachfrage als Funktion des Budgets und der Güterpreise her
Zunächst mithilfe des Lagrange Ansatzes (also ein bisschen Analysis)
Anschließend bilden wir Intuition mithilfe der grafischen Lösung im Zweigüterfall
Im nächsten Schritt können wir dann über Konsument:innen aggregieren
, um die Marktnachfrage zu erhalten
\[ \mathrm{max}_{\boldsymbol{x}} \ \ u(\boldsymbol{x}) \ \ \ \ \ \text{u.d.N.} \ \ \ \ \boldsymbol{x}'\boldsymbol{p} \leq m \]
\[ \left. \frac{\partial u(.)}{\partial x_i} \right |_{\boldsymbol{x^*}} = MU_i|_{\boldsymbol{x^*}} = \lambda^* p_i \ \ \ \ \ \ \ \forall i \]
\[ m = \boldsymbol{x^*} \ ' \boldsymbol{p} \]
Dividieren wir die Bedingungen erster Ordnung für zwei Güter \(i\) und \(j\) durcheinander und multiplizieren mit \(-1\), erhalten wir einen richtig nützlichen Ausdruck: \[ \underbrace{ \left. -\frac{\frac{\partial u(.)}{\partial x_i}}{\frac{\partial u(.)}{\partial x_j}} \right |_{\boldsymbol{x^*}} = \left. - \frac{MU_i}{MU_j} \right |_{\boldsymbol{x^*}}}_{\text{Grenzrate der Substitution}} = \underbrace{-\frac{p_i}{p_j}}_{\text{Steigung der Budgetgeraden}} \]
Wie schon antizipiert, erfüllt das optimale Güterbündel die oben erwähnte Tangenzialbedingung von Indifferenzkurve und Budgetgerade
Weitere Intuition:
Nehmen wir an, dass für ein Güterbündel \(MRS(x_1',x_2')>p_1/p_2\): der relative Grenznutzen von Gut 1 ist somit hoch im Vergleich zum relativen Preis. Somit möchte man mehr von Gut 1 und weniger von Gut 2 konsumieren
Bei diesem sub-optimalen Güterbündel würde man also gerne auf das relativ teure Gut 2 verzichten und mehr vom relativ billigen Gut 1 konsumieren
Für Fortgeschrittene: \(\lambda\) ist der Grenznutzen des Einkommens bzw. sein Schattenpreis
Verifizieren Sie das bitte in der grafischen Analyse weiter unten.
Mit einer expliziten Nutzenfunktion können wir nun die individuelle Nachfrage ausrechnen:
\[ u(x_1,x_2)=x_1^{\alpha}x_2^{1-\alpha} \ \ \ \ \ \text{mit} \ \alpha \in (0,1) \]
\[ -\frac{\alpha}{1-\alpha} \frac{x_2^*}{x_1^*} = - \frac{p_1}{p_2} \ \ \ \Leftrightarrow \ \ \ x_2^* = \frac{1-\alpha}{\alpha} \frac{p_1}{p_2}x_1^* \] \[ m=x_1^*p_1 + x_2^*p_2 \]
\[ x_1^* \equiv x_1(p_1,p_2,m) = \frac{\alpha \ m}{p_1}, \ \ \ x_2^*\equiv x_2(p_1,p_2,m) = \frac{(1-\alpha) \ m}{p_2} \]
#| standalone: true
#| viewerHeight: 600
library(shiny)
options(shiny.mathjax.url = "https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.7/MathJax.js")
library(ggplot2)
# Define UI
ui <- fluidPage(
br(),
withMathJax(),
sidebarLayout(
sidebarPanel(
h3("Nutzenmaximierung"),
tabsetPanel(
tabPanel("Hauptmenü", width = "400px",
br(),
p("\\(\\alpha\\) ist der Hauptparameter für die Nutzenfunktion. Unter \"Erweitert\" finden Sie weitere Optionen und können Budgetbeschränkungen umschalten."),
sliderInput(inputId = "alpha",
label = "Wähle \\(\\alpha\\)",
min = 0.01,
max = 0.99,
value = 0.5,
step = 0.01),
selectInput("utilityType",
"Wähle Nutzenfunktion:",
choices = c("Cobb-Douglas" = "cd",
"Perfekte Substitute" = "ps",
"Perfekte Komplemente" = "pc"
# ,
# "CES" = "ces"
)),
uiOutput('formula'),
checkboxInput("showBudgetLine",
"Zeige Budgetbeschränkung",
value = FALSE),
checkboxInput("showIndifferenceCurve",
"Zeige Indifferenzkurven",
value = FALSE)
),
tabPanel("Erweitert",
br(),
sliderInput("Px",
"Preis von Gut 1",
min = 1,
max = 5,
value = 4,
step = 0.1),
sliderInput("Py",
"Preis von Gut 2",
min = 1,
max = 5,
value = 2,
step = 0.1),
sliderInput("budget",
"Budget",
min = 100,
max = 300,
value = 200,
step = 1),
br(),
actionButton("reset", "Reset")
)
)
),
mainPanel(
align="center",
plotOutput(outputId = "utilityPlot", height = "550px", width = "600px"),
)
)
)
# Define server logic
server <- function(input, output) {
# Define utility functions
utility_function <- function(alpha, x, y, type) {
if (type == "cd") {
return(x^alpha * y^(1 - alpha))
}
if (type == "ps") {
return(alpha*x + (1-alpha)*y)
}
if (type == "pc") {
return(pmin(alpha*x, y))
}
# if (type == "ces") {
# rho = 0.5
# return((alpha*x^rho + (1-alpha)*y^rho)^(1/rho))
# }
}
# Find maximal utility
maximizeUtility <- function(budget, Px, Py, alpha, type) {
if (type == "cd") {
quantity_x <- (alpha * budget) / Px
quantity_y <- ((1 - alpha) * budget) / Py
max_utility <- utility_function(alpha, quantity_x, quantity_y, "cd")
} else if (type == "ps") {
utility_per_dollar_x <- alpha / Px
utility_per_dollar_y <- (1 - alpha) / Py
if (utility_per_dollar_x > utility_per_dollar_y) {
quantity_x <- budget / Px
quantity_y <- 0
} else {
quantity_x <- 0
quantity_y <- budget / Py
}
max_utility <- utility_function(alpha, quantity_x, quantity_y, "ps")
} else if (type == "pc") {
quantity_x <- budget / (Px + alpha * Py)
quantity_y <- alpha * (budget / (Px + alpha * Py))
max_utility <- utility_function(alpha, quantity_x, quantity_y, "pc")
}
# else if (type == "ces") {
# objective_function <- function(x) {
# y <- (budget - Px*x) / Py
# utility_function(alpha, x, y, "ces")
# }
# lower_bound <- 0
# upper_bound <- budget / Px
# optimization_result <- optimize(objective_function, interval = c(lower_bound, upper_bound), maximum = TRUE)
# quantity_x <- optimization_result$maximum
# quantity_y <- (budget - Px*quantity_x) / Py
# max_utility <- optimization_result$objective
# }
else {
stop("Unknown utility function type.")
}
return(list(max_utility = max_utility, quantity_x = quantity_x, quantity_y = quantity_y))
}
output$utilityPlot <- renderPlot({
alpha <- input$alpha
Px <- input$Px
Py <- input$Py
budget <- input$budget
type <- input$utilityType
showBudgetLine <- input$showBudgetLine
showIndifferenceCurve <- input$showIndifferenceCurve
maxutil_all <- maximizeUtility(budget, Px, Py, alpha, type)
maxutil <- maxutil_all$max_utility
quantity_x <- maxutil_all$quantity_x
quantity_y <- maxutil_all$quantity_y
x <- c(seq(1, 100, by = 2), seq(round(quantity_x*0.75, 1), round(quantity_x*1.25, 1), by = .1))
y <- c(seq(1, 100, by = 2), seq(round(quantity_y*0.75, 1), round(quantity_y*1.25, 1), by = .1))
grid <- expand.grid(x = x, y = y)
grid$utility <- utility_function(alpha, grid$x, grid$y, type)
if(showIndifferenceCurve) {
plot <- ggplot(grid, aes(x = x, y = y)) +
geom_contour(aes(z = utility), breaks = c(maxutil), color = "red") +
geom_contour(aes(z = utility), breaks = c(maxutil*0.8, maxutil*1.2), color = "red", linetype = "dashed") +
coord_cartesian(xlim = c(0, 100), ylim = c(0, 100)) +
theme_minimal()+
labs(x = expression(x[1]), y = expression(x[2])) +
theme(
axis.title.x = element_text(size = 20), # Adjust the font size of x-axis label
axis.title.y = element_text(size = 20) # Adjust the font size of y-axis label
)
} else if(showBudgetLine){
plot <- ggplot(grid, aes(x = x, y = y)) +
geom_abline(intercept = budget/Py, slope = -Px/Py, color = "blue") +
geom_blank() +
coord_cartesian(xlim = c(0, 100), ylim = c(0, 100)) +
theme_minimal()+
labs(x = expression(x[1]), y = expression(x[2])) +
theme(
axis.title.x = element_text(size = 20), # Adjust the font size of x-axis label
axis.title.y = element_text(size = 20) # Adjust the font size of y-axis label
)
} else {
plot <- ggplot(grid, aes(x = x, y = y)) +
coord_cartesian(xlim = c(0, 100), ylim = c(0, 100)) +
theme_minimal()+
labs(x = expression(x[1]), y = expression(x[2])) +
theme(
axis.title.x = element_text(size = 20), # Adjust the font size of x-axis label
axis.title.y = element_text(size = 20) # Adjust the font size of y-axis label
)
}
if(showBudgetLine && showIndifferenceCurve){
plot <- plot + geom_abline(intercept = budget/Py, slope = -Px/Py, color = "blue")+
annotate("segment", x = quantity_x, xend = quantity_x, y = 0, yend = quantity_y, linetype = "dashed")+
annotate("segment", x = 0, xend = quantity_x, y = quantity_y, yend = quantity_y, linetype = "dashed")+
annotate("label", x = quantity_x, y = 0, label = round(quantity_x, 2))+
annotate("label", x = 0, y = quantity_y, label = round(quantity_y, 2))+
geom_contour(aes(z = utility), breaks = c(maxutil), color = "red") +
geom_contour(aes(z = utility), breaks = c(maxutil*0.8, maxutil*1.2), color = "red", linetype = "dashed") +
coord_cartesian(xlim = c(0, 100), ylim = c(0, 100)) +
theme_minimal()+
labs(x = expression(x[1]), y = expression(x[2])) +
theme(
axis.title.x = element_text(size = 20), # Adjust the font size of x-axis label
axis.title.y = element_text(size = 20) # Adjust the font size of y-axis label
)
}
plot
})
observeEvent(input$reset, {
updateSliderInput(inputId = "alpha", value = 0.5)
updateCheckboxInput(inputId = "showBudgetLine", value = FALSE)
updateCheckboxInput(inputId = "showIndifferenceCurve", value = FALSE)
updateSliderInput(inputId = "Px", value = 4)
updateSliderInput(inputId = "Py", value = 2)
updateSliderInput(inputId = "budget", value = 200)
})
output$formula <- renderUI({
formula <- switch(input$utilityType,
"cd" = "$$U(x_1, x_2) = x_1^{\\alpha} x_2^{1-\\alpha}$$",
"ps" = "$$U(x_1, x_2) = \\alpha x_1 + (1-\\alpha) x_2$$",
"pc" = "$$U(x_1, x_2) = \\min(\\alpha x_1, x_2)$$",
#"ces" = "$$U(x, y) = (\\alpha x^{\\rho} + (1-\\alpha) y^{\\rho})^{\\frac{1}{\\rho}}$$",
"")
withMathJax("Formel: ", formula)
})
}
# Run the application
shinyApp(ui = ui, server = server)
Teamarbeit: Gehen Sie zurück auf Folie 31 und spielen Sie mit dem Einkommensparameter herum
Wie verändern sich Budgetgerade und Indifferenzkurven?
Wie verändert sich das Nachfragebündel?
Wie sieht das ganze mit unterschiedlichen Präferenzen aus?
Viele Güter sind normal
: bei höherem Budget wird mehr konsumiert
Einkommens-Expansionspfad
im Zweigüterfall und die Engel-Kurve
haben eine monoton positive Steigung (siehe nächste Folie)Einige Güter sind (abschnittsweise) inferior
: die Nachfrage reduziert sich bei höherem Budget
Dies betrifft vor allem Güter mit niedriger Qualität
Die Engel-Kurve fällt und der Einkommens-Expansionspfad ist “gewunden”
Steigt die Nachfrage schneller als das Budget (im Sinne einer Elastizität), spricht man von einem Luxusgut
; steigt sie langsamer, ist es ein notwendiges Gut
Teamarbeit: Gehen Sie zurück auf Folie 31 und spielen Sie mit einem der Preise herum
Wie verändern sich Budgetgerade und Indifferenzkurven?
Wie verändert sich das Nachfragebündel?
Wie sieht es mit unterschiedlichen Präferenzen aus?
de.statista.com
Eine Preissteigerung hat immer zwei Effekte:
Substitutionseffekt
: Andere Güter werden relativ billiger, sodass Konsumenten ‘wegsubstituieren’Einkommenseffekt
: Das Preisniveau steigt insgesamt an, sodass das reale
Budget kleiner wirdMathematisch kann man leicht die Slutzky Identität
herleiten
\[ \underbrace{\frac{\partial x_1(p_1, \ p_2, \bar{m})}{\partial p_1}}_{\text{Gesamteffekt (?)}} \equiv \underbrace{\frac{\partial x_1^S(p_1,\ p_2, \ \bar{x}_1,\bar{x}_2)}{\partial p_1}}_{\text{Substitutionseffekt (-)}} - \underbrace{\frac{\partial x_1(p_1, \ p_2, \bar{m})}{\partial m} \bar{x}_1 }_{\text{Einkommenseffekt (?)}}, \]
Könnte es sein, dass ein Gut stärker nachgefragt wird, wenn sein Preis steigt?
Haben Sie Beispiele?
Slutzky zeigt uns: Prinzipiell kann der Einkommenseffekt so stark sein, dass er den Substitutionseffekt überkompensiert; solche Güter heißen Giffen Güter
Empirische Evidenz
Jensen/Miller (2008): Reis und Fleisch Konsum extrem armer Menschen
Feldexperiment in der Provinz Hunan: randomisierte Zuteilung von Gutscheinen für Reis an Haushalte
Reiskonsum fiel, insbesondere in Hauhalten mit einem “mittelhohen” Einkommen
Bei den Präferenzen haben wir bereits informell von perfekten Substituten und Komplementen gesprochen, dies aber nicht definiert
Gut \(i\) ist ein Substitut (Komplement) für Gut \(j\neq i\), wenn \(\partial x_i(\boldsymbol{p},m)/\partial p_j > 0\) \((<0)\)
Bei vielen Gütern ist dies eine Matrix mit vielen indirekten Effekten, aber wir beschränken uns auf Brutto-Substitute und -Komplemente
Beispiel: Im Fall der Cobb-Douglas Nachfrage sind Güter weder das eine, noch das andere
\[ x_i(p_i) = \frac{\alpha_i \ m}{p_i} \]
Um zur Marktnachfrage zu gelangen, die wir einem Angebot gegenüberstellen können, verändern wir den Preis eines Gutes ceteris paribus und ermitteln zunächst die individuelle Nachfrage
Bei normalen Gütern fällt diese Funktion, wie Sie bei Ihren Explorationen bereits feststellen konnten
Die Marktnachfrage von \(n\) Konsument:innen ergibt sich als die Summe aller individuellen Nachfragen:
\[ X_i(\boldsymbol{p},\boldsymbol{m}) \equiv \sum_{c=1}^{n} x_i^c(\boldsymbol{p},m^c) \]
Wenn die Präferenzen aller Konsument:innen bestimmte Bedingungen erfüllen, können wir vernachlässigen, dass die Marktnachfrage von der Verteilung der Einkommen abhängt
repräsentativen Konsumenten
mit Budget \(M=\sum m^c\), der sich wie die Gesamtheit der Konsumenten verhält#| standalone: true
#| viewerHeight: 600
library(shiny)
library(shinydashboard)
library(ggplot2)
library(graphics)
library(ggpattern)
library(dplyr)
library(purrr)
library(bslib)
library(bs4Dash)
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
tabsetPanel(
tabPanel(h5("Einstellungen"),
br(),
checkboxInput("supp", "Inverses Angebot anzeigen", value = FALSE),
checkboxInput("dem", "Inverse Nachfrage anzeigen", value = FALSE),
sliderInput("slope_s", "Steigung Angebot", min = 0, max = 10, value = 1, step = 0.5),
sliderInput("slope_d", "Steigung Nachfrage", min = -10, max = 0, value = -1, step = 0.5),
numericInput("absch_d", "Achsenabschnitt Nachfrage", min = 0, max = 100, value = 75),
actionButton("reset", "Reset")
),
tabPanel(h5("Wohlfahrt"),
checkboxInput("cs", "Konsumentenrente anzeigen", value = FALSE),
checkboxInput("ps", "Produzentenrente anzeigen", value = FALSE),
br(),
uiOutput('kons_r')
),
tabPanel(h5("Steuern"),
sliderInput("tax", "Steuerrate t", min = -30, max = 30, value = 0, step = 1),
br(),
uiOutput("steu_totg")
)
)
),
mainPanel(align = "center",
plotOutput(outputId = "ggwplot", height = "500px", width = "600px"),
),
)
)
server <- function(input, output, session) {
angebot <- function(a_s, x) {
# p_s <- (x - 5)/a_s
p_s <- a_s * x + 5
return(p_s)
}
nachfrage <- function(a_d, b_d, x){
# p_d <- (x - b_d)/a_d
p_d <- a_d * x + b_d
return(p_d)
}
opt <- function(a_s, a_d, b_d) {
# p_opt <- (b_d - 5) / (a_s - a_d)
# x_opt <- a_d * p_opt + b_d
x_opt <- (b_d - 5) / (a_s - a_d)
p_opt <- a_d * x_opt + b_d
return(list(p_opt = p_opt, x_opt = x_opt))
}
observeEvent(list(input$tax, input$cs, input$ps, input$supp, input$dem, input$slope_d, input$slope_s, input$absch_d), {
a_s <- input$slope_s
a_d <- input$slope_d
b_d <- input$absch_d
cs <- input$cs
ps <- input$ps
x_v <- seq(0, 100, by = 0.5)
p_s <- angebot(a_s, x_v)
p_d <- nachfrage(a_d, b_d, x_v)
t <- input$tax
if (t != 0) {
grid <- tibble(
x_val = x_v,
S = p_s + t,
D = p_d
)
Ergebnisse <- opt(a_s, a_d, b_d)
#p_s_opt <- (Ergebnisse$p_opt + (t*a_d)/(a_s-a_d))
# p_d_opt <- (Ergebnisse$p_opt + (t*a_s)/(a_s-a_d))
p_s_opt <- (((t - b_d)/a_d)+(5/a_s))/((1/a_s)-(1/a_d))
p_d_opt <- p_s_opt + t
x_t <- (p_s_opt - 5)/a_s
# p_opt <- (b_d-5)/(a_s-a_d)
# x_opt <- a_s * p_opt + 5
x_opt <- (b_d - 5) / (a_s - a_d)
p_opt <- a_d * x_opt + b_d
}
else {
grid <- tibble(
x_val = x_v,
S = p_s,
D = p_d
)
Ergebnisse <- opt(a_s, a_d, b_d)
p_opt <- Ergebnisse$p_opt
x_opt <- Ergebnisse$x_opt
}
output$ggwplot <- renderPlot({
if (input$dem == TRUE && input$supp == TRUE) {
g_plot <- ggplot(grid) +
geom_line(aes(x = x_val, y = D, color = "Nachfrage"), size = 1.3) +
geom_line(aes(x = x_val, y = S, color = "Angebot"), size = ifelse(t != 0, 1, 1.3), linetype = ifelse(t != 0, "dashed", "solid")) +
scale_color_manual(values = c("Angebot" = "blue", "Nachfrage" = "red")) +
guides(color = guide_legend(title = "Kurven", position = "bottom", title.position = "left", title.hjust = 0.5)) +
coord_cartesian(xlim = c(-10, 100), ylim = c(-5, 100)) +
theme_minimal() +
labs(x = "Menge y", y = "Preis p") +
theme(
axis.text = element_text(size = 14),
axis.title = element_text(size = 16),
plot.title = element_text(size = 20),
legend.position = c(0.9, 0.9), # position -> legend
legend.justification = c(0.5, 0.5), # Top right corner
legend.background = element_rect(fill = "white", color = "black"),
legend.key = element_rect(fill = "white", color = "white")
)
} else if (input$dem == TRUE && input$supp == FALSE) {
g_plot <- ggplot(grid) +
geom_line(aes(x = x_val, y = D, color = "Nachfrage"), size = 1.3) +
scale_color_manual(values = c("Nachfrage" = "red")) +
guides(color = guide_legend(title = "Kurven", position = "bottom", title.position = "left", title.hjust = 0.5)) +
coord_cartesian(xlim = c(-10, 100), ylim = c(-5, 100)) +
theme_minimal() +
labs(x = "Menge y", y = "Preis p") +
theme(
axis.text = element_text(size = 14),
axis.title = element_text(size = 16),
plot.title = element_text(size = 20),
legend.position = c(0.9, 0.9), # Adjust this as necessary to position the legend
legend.justification = c(0.5, 0.5), # Top right corner
legend.background = element_rect(fill = "white", color = "black"),
legend.key = element_rect(fill = "white", color = "white")
)
} else if (input$dem == FALSE && input$supp == TRUE ) {
g_plot <- ggplot(grid) +
geom_line(aes(x = x_val, y = S, color = "Angebot"), size = ifelse(t != 0, 1, 1.3), linetype = ifelse(t != 0, "dashed", "solid")) +
scale_color_manual(values = c("Angebot" = "blue")) +
guides(color = guide_legend(title = "Kurven", position = "bottom", title.position = "left", title.hjust = 0.5)) +
coord_cartesian(xlim = c(-10, 100), ylim = c(-5, 100)) +
theme_minimal() +
labs(x = "Menge y", y = "Preis p") +
theme(
axis.text = element_text(size = 14),
axis.title = element_text(size = 16),
plot.title = element_text(size = 20),
legend.position = c(0.9, 0.9), # Adjust this as necessary to position the legend
legend.justification = c(0.5, 0.5), # Top right corner
legend.background = element_rect(fill = "white", color = "black"),
legend.key = element_rect(fill = "white", color = "white")
)
} else {
g_plot <- ggplot(grid) +
geom_line(aes(x = x_val, y = D), color = "white", size = 0.1) +
coord_cartesian(xlim = c(-5, 100), ylim = c(-5, 100)) +
theme_minimal() +
labs(x = "Menge y", y = "Preis p") +
theme(
axis.text = element_text(size = 14),
axis.title = element_text(size = 16),
plot.title = element_text(size = 20),
legend.position = c(0.9, 0.9), # Adjust this as necessary to position the legend
legend.justification = c(0.5, 0.5), # Top right corner
legend.background = element_rect(fill = "white", color = "black"),
legend.key = element_rect(fill = "white", color = "white")
)
}
if (input$dem && !is.null(p_opt) && cs == TRUE && t == 0) {
g_plot <- g_plot +
geom_ribbon_pattern(data = grid %>% filter(x_val <= x_opt),
aes(x = x_val, ymin = p_opt, ymax = D, fill = "Konsumentenrente"),
# fill = "#FF9999",
pattern = "stripe",
pattern_fill = "red",
pattern_angle = 45,
pattern_density = 0.3,
pattern_spacing = 0.01,
alpha = 0.3)
# annotate("Text", x = -5, y = p_opt + 15, label = "KR", color = "red", size = 7)
} else if (input$dem && !is.null(p_opt) && cs == TRUE && t != 0) {
g_plot <- g_plot +
geom_ribbon_pattern(data = grid %>% filter(x_val <= x_t),
aes(x = x_val, ymin = p_d_opt, ymax = D, fill = "Konsumentenrente" ),
# fill = "#FF9999",
pattern = "stripe",
pattern_fill = "red",
pattern_angle = 45,
pattern_density = 0.3,
pattern_spacing = 0.01,
alpha = 0.3)
}
if (input$supp && !is.null(p_opt) && input$ps && t == 0) {
g_plot <- g_plot +
geom_ribbon_pattern(data = grid %>% filter(x_val <= x_opt),
aes(x = x_val, ymin = S, ymax = p_opt, fill = "Produzentenrente"),
# fill = "#ADD8E6",
pattern = "stripe",
pattern_fill = "blue",
pattern_angle = 135,
pattern_density = 0.3,
pattern_spacing = 0.01,
alpha = 0.3)
# annotate("text", x = -5, y = p_opt - 15, label = "PS", color = "blue", size = 7)
} else if (input$supp && !is.null(p_opt) && input$ps && t != 0) {
g_plot <- g_plot +
geom_ribbon_pattern(data = grid %>% filter(x_val <= x_t),
aes(x = x_val, ymin = S - t, ymax = p_s_opt, fill = "Produzentenrente"),
# fill = "#ADD8E6",
pattern = "stripe",
pattern_fill = "blue",
pattern_angle = 135,
pattern_density = 0.3,
pattern_spacing = 0.01,
alpha = 0.3)
}
if (input$supp && !is.null(p_opt) && t > 0) {
g_plot <- g_plot +
geom_ribbon(data = grid %>% filter(x_val <= x_t),
aes(x = x_val, ymin = p_s_opt, ymax = p_opt, fill = "Steuererträge"),
# fill = "grey",
alpha = 1) +
geom_ribbon(data = grid %>% filter(x_val <= x_t),
aes(x = x_val, ymin = p_opt, ymax = p_d_opt, fill = "Steuererträge"),
# fill = "grey",
alpha = 1) +
geom_ribbon(data = grid %>% filter(x_val >= x_t & x_val <= x_opt),
aes(x = x_val, ymin = S - t, ymax = D, fill = "Wohlfahrtsverlust"),
# fill = "black",
alpha = 1)
# annotate("text", x = -5, y = p_opt - 15, label = "PS", color = "blue", size = 7)
}
if (t != 0) {
g_plot <- g_plot +
geom_line(aes(x = x_val, y = S - t, color = "Angebot"), size = 1.3, linetype = "solid")
}
label1 <- bquote(p[d] ~ "≈")
label2 <- bquote(p[s] ~ "≈")
label3 <- bquote(x[t] ~ "≈")
if (t != 0) {
g_plot <- g_plot +
geom_segment(aes(x = x_t, xend = x_t, y = -5, yend = p_d_opt), color = "violet", linetype = "longdash", size = 0.7) +
geom_segment(aes(x = 0, xend = x_t, y = p_d_opt, yend = p_d_opt), color = "violet", linetype = "longdash", size = 0.7) +
geom_segment(aes(x = 0, xend = x_t, y = p_s_opt, yend = p_s_opt), color = "violet", linetype = "longdash", size = 0.7) +
annotate("text", x = x_t, y = -5, label = as.expression(bquote(.(label3) ~ .(round(x_t)))), vjust = 1, hjust = 1, color = "violet", size = 5) +
annotate("text", x = 0, y = p_d_opt, label = as.expression(bquote(.(label1) ~ .(round(p_d_opt)))), vjust = 0.5, hjust = 1, color = "violet", size = 5) +
annotate("text", x = 0, y = p_s_opt, label = as.expression(bquote(.(label2) ~ .(round(p_s_opt)))), vjust = 0.5, hjust = 1, color = "violet", size = 5)
}
if ( t < 0) {
g_plot <- g_plot +
geom_segment(aes(x = x_t, xend = x_t, y = -5, yend = p_s_opt), color = "violet", linetype = "longdash", size = 0.7)
}
if (input$dem == TRUE && input$supp == TRUE) {
g_plot <- g_plot +
geom_segment(aes(x = x_opt, xend = x_opt, y = 0, yend = p_opt), color = "orange", linetype = "longdash", size = 0.7) +
geom_segment(aes(x = 0, xend = x_opt, y = p_opt, yend = p_opt), color = "orange", linetype = "longdash", size = 0.7) +
annotate("text", x = x_opt, y = 0, label = paste("x* ≈ ", round(x_opt)), vjust = 1, hjust = 0.5, color = "orange", size = 5) +
annotate("text", x = 0, y = p_opt, label = paste("p* ≈ ", round(p_opt)), vjust = 0.5, hjust = 1, color = "orange", size = 5)
}
g_plot <- g_plot +
scale_color_manual(
values = c("Angebot" = "blue", "Nachfrage" = "red"),
name = "Kurven"
) +
scale_fill_manual(
values = c("Konsumentenrente" = "#FF9999", "Produzentenrente" = "#ADD8E6", "Steuererträge" = "grey", "Wohlfahrtsverlust" = "black"), name = "") +
guides(color = guide_legend(title = "Geraden", position = "bottom", title.position = "left", title.hjust = 1))
print(g_plot)
})
})
observeEvent(input$reset, {
updateSliderInput(inputId = "slope_d", value = -1)
updateSliderInput(inputId = "slope_s", value = 1)
updateSliderInput(inputId = "tax", value = 0)
updateNumericInput(inputId = "absch_d", value = 75)
updateCheckboxInput(inputId = "cs", value = FALSE)
updateCheckboxInput(inputId = "ps", value = FALSE)
})
kons_r <- reactiveVal(0)
prod_r <- reactiveVal(0)
observeEvent(list(input$cs, input$ps, input$supp, input$tax, input$dem, input$slope_d, input$slope_s, input$absch_d), {
a_s <- input$slope_s
a_d <- input$slope_d
b_d <- input$absch_d
Ergebnisse <- opt(a_s, a_d, b_d)
p_opt <- Ergebnisse$p_opt
x_opt <- Ergebnisse$x_opt
t <- input$tax
p_s_opt <- (((t - b_d)/a_d)+(5/a_s))/((1/a_s)-(1/a_d))
p_d_opt <- p_s_opt + t
x_t <- (p_s_opt - 5)/a_s
if (input$cs == TRUE && input$supp == TRUE && input$dem == TRUE && t == 0) {
kons_r(((b_d-p_opt) * x_opt) / 2)
} else if (input$cs == TRUE && input$supp == TRUE && input$dem == TRUE && t != 0) {
kons_r(((b_d-p_d_opt) * x_t) / 2)
} else {
kons_r(0)
}
if (input$ps == TRUE && input$supp == TRUE && input$dem == TRUE && t == 0) {
prod_r((p_opt * x_opt) / 2)
} else if (input$cs == TRUE && input$supp == TRUE && input$dem == TRUE && t != 0) {
prod_r((p_s_opt * x_t) / 2)
} else {
prod_r(0)
}
})
output$kons_r <- renderUI({
kons_r_r <- round(kons_r(), digits = 2)
prod_r_r <- round(prod_r(), digits = 2)
withMathJax(HTML(paste("Konsumentenrente:", kons_r_r, "<br>",
"Produzentenrente:", prod_r_r))
)
})
steu_ber <- reactiveVal(0)
totg_ber <- reactiveVal(0)
observeEvent(list(input$cs, input$ps, input$supp, input$tax, input$dem, input$slope_d, input$slope_s, input$absch_d), {
a_s <- input$slope_s
a_d <- input$slope_d
b_d <- input$absch_d
Ergebnisse <- opt(a_s, a_d, b_d)
p_opt <- Ergebnisse$p_opt
x_opt <- Ergebnisse$x_opt
t <- input$tax
p_s_opt <- (((t - b_d)/a_d)+(5/a_s))/((1/a_s)-(1/a_d))
p_d_opt <- p_s_opt + t
x_t <- (p_s_opt - 5)/a_s
if (input$supp == TRUE && input$dem == TRUE && t > 0) {
steu_ber(-1 * (x_t*(p_d_opt-p_s_opt)))
totg_ber((p_opt-p_s_opt)*(x_opt-x_t)/2 + (p_d_opt-p_opt)*(x_opt-x_t)/2 )
}
if (input$supp == TRUE && input$dem == TRUE && t < 0) {
steu_ber(x_t*(p_s_opt-p_d_opt))
totg_ber((p_s_opt-p_opt)*(x_t-x_opt)/2 + (p_opt-p_d_opt)*(x_t-x_opt)/2 )
}
})
output$steu_totg <- renderUI({
steu <- round(steu_ber(), digits = 2)
totg <- round(totg_ber(), digits = 2)
withMathJax(HTML(paste("Steuereinnahmen:", -steu, "<br>",
"Wohlfahrtsverlust:", totg))
)
})
}
shinyApp(ui = ui, server = server)
Die Eigenschaften der Nachfragefunktion spielen eine zentrale Rolle in der VWL
Preissetzung von Unternehmen
Marktreaktionen auf Steuern, Subventionen, Friktionen oder Schocks
Wohlfahrtseffekte
Um das besser zu verstehen, brauchen wir ein paar wichtige Konzepte
Preiselastizität
Einkommenselastizität
Konsumentenrente
Oft sprechen wir aus verschiedenen Gründen von preiselastischer
oder preisUNelastischer
Nachfrage
Preiselastizität
der Nachfrage nach Gut 1\[ \varepsilon_{X_1,p_1} \equiv \frac{\frac{\partial X_1(p_1)}{X_1(p_1)}*100}{\frac{\partial p_1}{p_1}*100} = \frac{\partial X_1(p_1)}{\partial p_1} \frac{p_1}{X_1(p_1)} \]
Teamarbeit: Gehen Sie zurück auf Folie 44 und verändern Sie die Nachfrageparamater so, dass die Nachfrage elastischer wird!
Nehmen wir Cobb-Douglas Präferenzen mit Nachfragefunktion
\[ x_i = \frac{\alpha_i \ m}{p_i} \]
Dann ist die Preiselastizität
\[ \varepsilon_{X_i,p_i} = \frac{\partial x_i(p_i)}{\partial p_i} \frac{p_i}{x_i(p_i)} = \frac{-\alpha_i \ m}{p_i^2} \frac{p_i^2}{\alpha_i \ m} = -1 \]
Cobb-Douglas Präferenzen erzeugen Constant Elasticity of Substitution (CES)
Nachfrage
Konsument:innen reduzieren ihre Nachfrage immer um ein Prozent, wenn der Preis um ein Prozent steigt
CES Präferenzen werden extrem häufig eingesetzt, da sie sehr angenehme Eigenschaften haben
Analog können wir die Einkommenselastizität von Gütern definieren:
\[ \varepsilon_{x_i,m} \equiv \frac{\partial x_i(p_i,m)}{\partial m} \frac{m}{x_i(p_i,m)} \]
Mithilfe dieser Elastizität können wir Güter nun formal kategorisieren
Wiederum mit Cobb-Dougles Präferenzen und Nachfragefunktion
\[ x_i = \frac{\alpha_i \ m}{p_i} \]
haben wir
\[ \varepsilon_{x_i,m} = \frac{\alpha_i}{p_i} \frac{m}{\frac{\alpha_i \ m}{p_i}} = 1 \]
Jede Einkommenserhöhung um ein Prozent erhöht die Nachfrage nach jedem Gut um ein Prozent
Die Engel-Kurve ist eine Gerade mit Steigung \(\alpha_i/p_i\)
Diese Präferenzen sind daher homothetisch
: die relativen Nachfragen sind unabhängig vom Einkommen
Die inverse Marktnachfrage gibt an, welchen Preis Konsument:innen maximal bereit sind zu zahlen, wenn sie eine bestimmte Menge erwerben wollen – diesen Preis nennt man Reservations-
oder Vorbehaltspreis
Der gezahlte Preis entspricht einem bestimmten Nutzenverlust, da andere Güter mit dem verausgabten Geld nicht mehr erworben werden können
Die Konsumentenrente
, ein Maß für die Wohlfahrt der Konsumentenseite, kann also über die Differenz zwischen inverser Nachfrage und dem Preis ermittelt werden
Dieses zentrale Konzept werden wir für die Analyse von Steuern, aber auch von Marktversagen brauchen!
#| standalone: true
#| viewerHeight: 600
library(shiny)
library(shinydashboard)
library(ggplot2)
library(graphics)
library(ggpattern)
library(dplyr)
library(purrr)
library(bslib)
library(bs4Dash)
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
tabsetPanel(
tabPanel(h5("Einstellungen"),
br(),
checkboxInput("supp", "Inverses Angebot anzeigen", value = FALSE),
checkboxInput("dem", "Inverse Nachfrage anzeigen", value = FALSE),
sliderInput("slope_s", "Steigung Angebot", min = 0, max = 10, value = 1, step = 0.5),
sliderInput("slope_d", "Steigung Nachfrage", min = -10, max = 0, value = -1, step = 0.5),
numericInput("absch_d", "Achsenabschnitt Nachfrage", min = 0, max = 100, value = 75),
actionButton("reset", "Reset")
),
tabPanel(h5("Wohlfahrt"),
checkboxInput("cs", "Konsumentenrente anzeigen", value = FALSE),
checkboxInput("ps", "Produzentenrente anzeigen", value = FALSE),
br(),
uiOutput('kons_r')
),
tabPanel(h5("Steuern"),
sliderInput("tax", "Steuerrate t", min = -30, max = 30, value = 0, step = 1),
br(),
uiOutput("steu_totg")
)
)
),
mainPanel(align = "center",
plotOutput(outputId = "ggwplot", height = "500px", width = "600px"),
),
)
)
server <- function(input, output, session) {
angebot <- function(a_s, x) {
# p_s <- (x - 5)/a_s
p_s <- a_s * x + 5
return(p_s)
}
nachfrage <- function(a_d, b_d, x){
# p_d <- (x - b_d)/a_d
p_d <- a_d * x + b_d
return(p_d)
}
opt <- function(a_s, a_d, b_d) {
# p_opt <- (b_d - 5) / (a_s - a_d)
# x_opt <- a_d * p_opt + b_d
x_opt <- (b_d - 5) / (a_s - a_d)
p_opt <- a_d * x_opt + b_d
return(list(p_opt = p_opt, x_opt = x_opt))
}
observeEvent(list(input$tax, input$cs, input$ps, input$supp, input$dem, input$slope_d, input$slope_s, input$absch_d), {
a_s <- input$slope_s
a_d <- input$slope_d
b_d <- input$absch_d
cs <- input$cs
ps <- input$ps
x_v <- seq(0, 100, by = 0.5)
p_s <- angebot(a_s, x_v)
p_d <- nachfrage(a_d, b_d, x_v)
t <- input$tax
if (t != 0) {
grid <- tibble(
x_val = x_v,
S = p_s + t,
D = p_d
)
Ergebnisse <- opt(a_s, a_d, b_d)
#p_s_opt <- (Ergebnisse$p_opt + (t*a_d)/(a_s-a_d))
# p_d_opt <- (Ergebnisse$p_opt + (t*a_s)/(a_s-a_d))
p_s_opt <- (((t - b_d)/a_d)+(5/a_s))/((1/a_s)-(1/a_d))
p_d_opt <- p_s_opt + t
x_t <- (p_s_opt - 5)/a_s
# p_opt <- (b_d-5)/(a_s-a_d)
# x_opt <- a_s * p_opt + 5
x_opt <- (b_d - 5) / (a_s - a_d)
p_opt <- a_d * x_opt + b_d
}
else {
grid <- tibble(
x_val = x_v,
S = p_s,
D = p_d
)
Ergebnisse <- opt(a_s, a_d, b_d)
p_opt <- Ergebnisse$p_opt
x_opt <- Ergebnisse$x_opt
}
output$ggwplot <- renderPlot({
if (input$dem == TRUE && input$supp == TRUE) {
g_plot <- ggplot(grid) +
geom_line(aes(x = x_val, y = D, color = "Nachfrage"), size = 1.3) +
geom_line(aes(x = x_val, y = S, color = "Angebot"), size = ifelse(t != 0, 1, 1.3), linetype = ifelse(t != 0, "dashed", "solid")) +
scale_color_manual(values = c("Angebot" = "blue", "Nachfrage" = "red")) +
guides(color = guide_legend(title = "Kurven", position = "bottom", title.position = "left", title.hjust = 0.5)) +
coord_cartesian(xlim = c(-10, 100), ylim = c(-5, 100)) +
theme_minimal() +
labs(x = "Menge y", y = "Preis p") +
theme(
axis.text = element_text(size = 14),
axis.title = element_text(size = 16),
plot.title = element_text(size = 20),
legend.position = c(0.9, 0.9), # position -> legend
legend.justification = c(0.5, 0.5), # Top right corner
legend.background = element_rect(fill = "white", color = "black"),
legend.key = element_rect(fill = "white", color = "white")
)
} else if (input$dem == TRUE && input$supp == FALSE) {
g_plot <- ggplot(grid) +
geom_line(aes(x = x_val, y = D, color = "Nachfrage"), size = 1.3) +
scale_color_manual(values = c("Nachfrage" = "red")) +
guides(color = guide_legend(title = "Kurven", position = "bottom", title.position = "left", title.hjust = 0.5)) +
coord_cartesian(xlim = c(-10, 100), ylim = c(-5, 100)) +
theme_minimal() +
labs(x = "Menge y", y = "Preis p") +
theme(
axis.text = element_text(size = 14),
axis.title = element_text(size = 16),
plot.title = element_text(size = 20),
legend.position = c(0.9, 0.9), # Adjust this as necessary to position the legend
legend.justification = c(0.5, 0.5), # Top right corner
legend.background = element_rect(fill = "white", color = "black"),
legend.key = element_rect(fill = "white", color = "white")
)
} else if (input$dem == FALSE && input$supp == TRUE ) {
g_plot <- ggplot(grid) +
geom_line(aes(x = x_val, y = S, color = "Angebot"), size = ifelse(t != 0, 1, 1.3), linetype = ifelse(t != 0, "dashed", "solid")) +
scale_color_manual(values = c("Angebot" = "blue")) +
guides(color = guide_legend(title = "Kurven", position = "bottom", title.position = "left", title.hjust = 0.5)) +
coord_cartesian(xlim = c(-10, 100), ylim = c(-5, 100)) +
theme_minimal() +
labs(x = "Menge y", y = "Preis p") +
theme(
axis.text = element_text(size = 14),
axis.title = element_text(size = 16),
plot.title = element_text(size = 20),
legend.position = c(0.9, 0.9), # Adjust this as necessary to position the legend
legend.justification = c(0.5, 0.5), # Top right corner
legend.background = element_rect(fill = "white", color = "black"),
legend.key = element_rect(fill = "white", color = "white")
)
} else {
g_plot <- ggplot(grid) +
geom_line(aes(x = x_val, y = D), color = "white", size = 0.1) +
coord_cartesian(xlim = c(-5, 100), ylim = c(-5, 100)) +
theme_minimal() +
labs(x = "Menge y", y = "Preis p") +
theme(
axis.text = element_text(size = 14),
axis.title = element_text(size = 16),
plot.title = element_text(size = 20),
legend.position = c(0.9, 0.9), # Adjust this as necessary to position the legend
legend.justification = c(0.5, 0.5), # Top right corner
legend.background = element_rect(fill = "white", color = "black"),
legend.key = element_rect(fill = "white", color = "white")
)
}
if (input$dem && !is.null(p_opt) && cs == TRUE && t == 0) {
g_plot <- g_plot +
geom_ribbon_pattern(data = grid %>% filter(x_val <= x_opt),
aes(x = x_val, ymin = p_opt, ymax = D, fill = "Konsumentenrente"),
# fill = "#FF9999",
pattern = "stripe",
pattern_fill = "red",
pattern_angle = 45,
pattern_density = 0.3,
pattern_spacing = 0.01,
alpha = 0.3)
# annotate("Text", x = -5, y = p_opt + 15, label = "KR", color = "red", size = 7)
} else if (input$dem && !is.null(p_opt) && cs == TRUE && t != 0) {
g_plot <- g_plot +
geom_ribbon_pattern(data = grid %>% filter(x_val <= x_t),
aes(x = x_val, ymin = p_d_opt, ymax = D, fill = "Konsumentenrente" ),
# fill = "#FF9999",
pattern = "stripe",
pattern_fill = "red",
pattern_angle = 45,
pattern_density = 0.3,
pattern_spacing = 0.01,
alpha = 0.3)
}
if (input$supp && !is.null(p_opt) && input$ps && t == 0) {
g_plot <- g_plot +
geom_ribbon_pattern(data = grid %>% filter(x_val <= x_opt),
aes(x = x_val, ymin = S, ymax = p_opt, fill = "Produzentenrente"),
# fill = "#ADD8E6",
pattern = "stripe",
pattern_fill = "blue",
pattern_angle = 135,
pattern_density = 0.3,
pattern_spacing = 0.01,
alpha = 0.3)
# annotate("text", x = -5, y = p_opt - 15, label = "PS", color = "blue", size = 7)
} else if (input$supp && !is.null(p_opt) && input$ps && t != 0) {
g_plot <- g_plot +
geom_ribbon_pattern(data = grid %>% filter(x_val <= x_t),
aes(x = x_val, ymin = S - t, ymax = p_s_opt, fill = "Produzentenrente"),
# fill = "#ADD8E6",
pattern = "stripe",
pattern_fill = "blue",
pattern_angle = 135,
pattern_density = 0.3,
pattern_spacing = 0.01,
alpha = 0.3)
}
if (input$supp && !is.null(p_opt) && t > 0) {
g_plot <- g_plot +
geom_ribbon(data = grid %>% filter(x_val <= x_t),
aes(x = x_val, ymin = p_s_opt, ymax = p_opt, fill = "Steuererträge"),
# fill = "grey",
alpha = 1) +
geom_ribbon(data = grid %>% filter(x_val <= x_t),
aes(x = x_val, ymin = p_opt, ymax = p_d_opt, fill = "Steuererträge"),
# fill = "grey",
alpha = 1) +
geom_ribbon(data = grid %>% filter(x_val >= x_t & x_val <= x_opt),
aes(x = x_val, ymin = S - t, ymax = D, fill = "Wohlfahrtsverlust"),
# fill = "black",
alpha = 1)
# annotate("text", x = -5, y = p_opt - 15, label = "PS", color = "blue", size = 7)
}
if (t != 0) {
g_plot <- g_plot +
geom_line(aes(x = x_val, y = S - t, color = "Angebot"), size = 1.3, linetype = "solid")
}
label1 <- bquote(p[d] ~ "≈")
label2 <- bquote(p[s] ~ "≈")
label3 <- bquote(x[t] ~ "≈")
if (t != 0) {
g_plot <- g_plot +
geom_segment(aes(x = x_t, xend = x_t, y = -5, yend = p_d_opt), color = "violet", linetype = "longdash", size = 0.7) +
geom_segment(aes(x = 0, xend = x_t, y = p_d_opt, yend = p_d_opt), color = "violet", linetype = "longdash", size = 0.7) +
geom_segment(aes(x = 0, xend = x_t, y = p_s_opt, yend = p_s_opt), color = "violet", linetype = "longdash", size = 0.7) +
annotate("text", x = x_t, y = -5, label = as.expression(bquote(.(label3) ~ .(round(x_t)))), vjust = 1, hjust = 1, color = "violet", size = 5) +
annotate("text", x = 0, y = p_d_opt, label = as.expression(bquote(.(label1) ~ .(round(p_d_opt)))), vjust = 0.5, hjust = 1, color = "violet", size = 5) +
annotate("text", x = 0, y = p_s_opt, label = as.expression(bquote(.(label2) ~ .(round(p_s_opt)))), vjust = 0.5, hjust = 1, color = "violet", size = 5)
}
if ( t < 0) {
g_plot <- g_plot +
geom_segment(aes(x = x_t, xend = x_t, y = -5, yend = p_s_opt), color = "violet", linetype = "longdash", size = 0.7)
}
if (input$dem == TRUE && input$supp == TRUE) {
g_plot <- g_plot +
geom_segment(aes(x = x_opt, xend = x_opt, y = 0, yend = p_opt), color = "orange", linetype = "longdash", size = 0.7) +
geom_segment(aes(x = 0, xend = x_opt, y = p_opt, yend = p_opt), color = "orange", linetype = "longdash", size = 0.7) +
annotate("text", x = x_opt, y = 0, label = paste("x* ≈ ", round(x_opt)), vjust = 1, hjust = 0.5, color = "orange", size = 5) +
annotate("text", x = 0, y = p_opt, label = paste("p* ≈ ", round(p_opt)), vjust = 0.5, hjust = 1, color = "orange", size = 5)
}
g_plot <- g_plot +
scale_color_manual(
values = c("Angebot" = "blue", "Nachfrage" = "red"),
name = "Kurven"
) +
scale_fill_manual(
values = c("Konsumentenrente" = "#FF9999", "Produzentenrente" = "#ADD8E6", "Steuererträge" = "grey", "Wohlfahrtsverlust" = "black"), name = "") +
guides(color = guide_legend(title = "Geraden", position = "bottom", title.position = "left", title.hjust = 1))
print(g_plot)
})
})
observeEvent(input$reset, {
updateSliderInput(inputId = "slope_d", value = -1)
updateSliderInput(inputId = "slope_s", value = 1)
updateSliderInput(inputId = "tax", value = 0)
updateNumericInput(inputId = "absch_d", value = 75)
updateCheckboxInput(inputId = "cs", value = FALSE)
updateCheckboxInput(inputId = "ps", value = FALSE)
})
kons_r <- reactiveVal(0)
prod_r <- reactiveVal(0)
observeEvent(list(input$cs, input$ps, input$supp, input$tax, input$dem, input$slope_d, input$slope_s, input$absch_d), {
a_s <- input$slope_s
a_d <- input$slope_d
b_d <- input$absch_d
Ergebnisse <- opt(a_s, a_d, b_d)
p_opt <- Ergebnisse$p_opt
x_opt <- Ergebnisse$x_opt
t <- input$tax
p_s_opt <- (((t - b_d)/a_d)+(5/a_s))/((1/a_s)-(1/a_d))
p_d_opt <- p_s_opt + t
x_t <- (p_s_opt - 5)/a_s
if (input$cs == TRUE && input$supp == TRUE && input$dem == TRUE && t == 0) {
kons_r(((b_d-p_opt) * x_opt) / 2)
} else if (input$cs == TRUE && input$supp == TRUE && input$dem == TRUE && t != 0) {
kons_r(((b_d-p_d_opt) * x_t) / 2)
} else {
kons_r(0)
}
if (input$ps == TRUE && input$supp == TRUE && input$dem == TRUE && t == 0) {
prod_r((p_opt * x_opt) / 2)
} else if (input$cs == TRUE && input$supp == TRUE && input$dem == TRUE && t != 0) {
prod_r((p_s_opt * x_t) / 2)
} else {
prod_r(0)
}
})
output$kons_r <- renderUI({
kons_r_r <- round(kons_r(), digits = 2)
prod_r_r <- round(prod_r(), digits = 2)
withMathJax(HTML(paste("Konsumentenrente:", kons_r_r, "<br>",
"Produzentenrente:", prod_r_r))
)
})
steu_ber <- reactiveVal(0)
totg_ber <- reactiveVal(0)
observeEvent(list(input$cs, input$ps, input$supp, input$tax, input$dem, input$slope_d, input$slope_s, input$absch_d), {
a_s <- input$slope_s
a_d <- input$slope_d
b_d <- input$absch_d
Ergebnisse <- opt(a_s, a_d, b_d)
p_opt <- Ergebnisse$p_opt
x_opt <- Ergebnisse$x_opt
t <- input$tax
p_s_opt <- (((t - b_d)/a_d)+(5/a_s))/((1/a_s)-(1/a_d))
p_d_opt <- p_s_opt + t
x_t <- (p_s_opt - 5)/a_s
if (input$supp == TRUE && input$dem == TRUE && t > 0) {
steu_ber(-1 * (x_t*(p_d_opt-p_s_opt)))
totg_ber((p_opt-p_s_opt)*(x_opt-x_t)/2 + (p_d_opt-p_opt)*(x_opt-x_t)/2 )
}
if (input$supp == TRUE && input$dem == TRUE && t < 0) {
steu_ber(x_t*(p_s_opt-p_d_opt))
totg_ber((p_s_opt-p_opt)*(x_t-x_opt)/2 + (p_opt-p_d_opt)*(x_t-x_opt)/2 )
}
})
output$steu_totg <- renderUI({
steu <- round(steu_ber(), digits = 2)
totg <- round(totg_ber(), digits = 2)
withMathJax(HTML(paste("Steuereinnahmen:", -steu, "<br>",
"Wohlfahrtsverlust:", totg))
)
})
}
shinyApp(ui = ui, server = server)
Erläutern Sie, welche Güterbündel sich Nachfrager überhaupt leisten können und von welchen Determinanten diese Menge abhängt
Gehen Sie alle Nutzenfunktionen anhand der interaktiven Grafik durch und erläutern Sie, warum die Indifferenzkurven die jeweilige Form annehmen
Wie findet man die optimale Nachfrage? Welche Herangehensweisen gibt es?
Nehmen Sie eine bestimmte Klasse von Nutzenfunktionen und versuchen Sie, mithilfe einer interaktiven Grafik Einkommens-Expansionspfade, Engel-Kurven und Nachfragefunktionen zu konstruieren
Suchen Sie sich einen Partner und erklären dieser Person die Begriffe “Preiselastizität”, “Einkommenselastizität” und “Konsumentenrente”
© Prof. Frank Pisch PhD | Fachgebiet Mikroökonomie