Skip to content

Instantly share code, notes, and snippets.

@farach
Created January 4, 2025 00:27
Show Gist options
  • Save farach/b48db0ae5092d58018a75e59e17cac83 to your computer and use it in GitHub Desktop.
Save farach/b48db0ae5092d58018a75e59e17cac83 to your computer and use it in GitHub Desktop.
This R script uses gganimate to simulate and visualize how firms adapt their configurations—single-layer or two-layer, human or AI—as AI knowledge levels ( 𝑧 𝐴 𝐼 z AI ​ ) increase. Inspired by the Artificial Intelligence in the Knowledge Economy model, it calculates profits for each setup and dynamically displays the best configurations over tim…
library(tidyverse)
library(gganimate)
# Parameters
h <- 0.02 # Time cost per worker for the solver
r <- 2 # Rental rate for one unit of compute
worker_grid <- seq(0.2, 0.8, by = 0.1) # Range of human worker knowledge
solver_grid <- seq(0.3, 1.0, by = 0.1) # Range of human solver knowledge
zAI_values <- seq(0.25, 0.95, by = 0.05) # Range of AI knowledge levels
# Functions
productivity_h <- function(z) 10 * z
wage_h <- function(z) 0.6 * productivity_h(z)
n_workers <- function(z) {
val <- 1 / (h * (1 - z))
return(pmin(val, 100)) # Cap at 100 workers
}
profit_single_human <- function(z) 4 * z
profit_single_ai <- function(zAI) 10 * zAI - r
profit_two_layer_hh <- function(s, z) {
n_z <- n_workers(z)
return(n_z * (s - wage_h(z)) - wage_h(s))
}
profit_two_layer_tA <- function(z, zAI) {
n_z <- n_workers(z)
return(n_z * (zAI * 10 - wage_h(z)) - r)
}
profit_two_layer_bA <- function(s, zAI) {
n_AI <- n_workers(zAI)
return(n_AI * (s * 10 - r) - wage_h(s))
}
# Create a dataset with varying zAI
df <- expand.grid(
z_worker = worker_grid,
s_solver = solver_grid,
zAI = zAI_values
) |>
mutate(
# 1) Single-layer HUMAN
pi_single_h = profit_single_human(z_worker),
# 2) Single-layer AI
pi_single_ai = profit_single_ai(zAI),
# 3) Two-layer, human-human
pi_hh = if_else(s_solver >= z_worker,
profit_two_layer_hh(s_solver * 10, z_worker),
NA_real_
),
# 4) Two-layer, AI as solver
pi_tA = profit_two_layer_tA(z_worker, zAI),
# 5) Two-layer, AI as worker
pi_bA = if_else(s_solver >= zAI,
profit_two_layer_bA(s_solver, zAI),
NA_real_
)
) |>
rowwise() |>
mutate(
best_profit = max(c_across(starts_with("pi_")), na.rm = TRUE),
best_config = case_when(
best_profit == pi_single_h ~ "Single-Layer Human",
best_profit == pi_single_ai ~ "Single-Layer AI",
best_profit == pi_hh ~ "Two-Layer Human-Human",
best_profit == pi_tA ~ "Two-Layer AI as Solver",
best_profit == pi_bA ~ "Two-Layer AI as Worker",
TRUE ~ NA_character_
)
) |>
ungroup()
# Animate the plot
p <- ggplot(df, aes(x = z_worker, y = s_solver, fill = best_config)) +
geom_tile(color = "white") +
labs(
title = "Best Firm Configuration by Worker & Solver Knowledge<br>",
subtitle = "AI Knowledge Level: {closest_state}<br>",
x = "Worker Knowledge (z)",
y = "Solver Knowledge (s)<br>",
fill = "Best Config:"
) +
theme_wl_void() +
theme(
legend.title = element_markdown(size = 12),
legend.text = element_markdown(size = 12),
axis.text = element_markdown(size = 12),
axis.title = element_markdown(size = 12),
axis.title.y = element_markdown(angle = 90),
plot.title = element_markdown(hjust = 0.5),
plot.subtitle = element_markdown(size = 12, hjust = 0.5),
plot.caption = element_markdown(size = 12),
panel.grid = element_blank(),
panel.grid.major = element_blank(),
panel.grid.minor = element_blank()
) +
transition_states(zAI, transition_length = 2, state_length = 1) +
ease_aes("linear")
# Save/render animation
animate(p, fps = 10, width = 800, height = 600)
anim_save("best_firm_config.gif", animation = last_animation())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment