@@ -240,23 +240,24 @@ Where $\text{Africa [i]}$ is an index variable which takes the value 1 for Afric
240240
241241``` {r}
242242rugged_clean <- rugged_clean %>%
243- mutate(african_status = ifelse(cont_africa == 1, "african ", "not african "))
243+ mutate(cont = ifelse(cont_africa == 1, "African ", "Not African "))
244244
245245b8.1 <- brm(data = rugged_clean,
246246 family = gaussian(),
247- log_gdp_std ~ 0 + african_status + rugged_std_centered,
247+ log_gdp_std ~ 0 + cont + rugged_std_centered,
248248 prior = c(
249- prior(normal(0.9, 0.1), class = b, coef = "african_statusafrican "),
250- prior(normal(1.1, 0.1), class = b, coef = "african_statusnotafrican "),
249+ prior(normal(0.9, 0.1), class = b, coef = "contAfrican "),
250+ prior(normal(1.1, 0.1), class = b, coef = "contNotAfrican "),
251251 prior(normal(0, 0.3), class = b, coef = "rugged_std_centered"),
252252 prior(exponential(1), class = sigma)
253253 ),
254254 iter = 2000, warmup = 1000, cores = 4, seed = 5,
255- backend = "cmdstanr", silent = 2, file = "fits/b08.1.1 ")
255+ backend = "cmdstanr", silent = 2, file = "fits/b08.1.2 ")
256256
257257# get_prior(data = rugged_clean,
258258# family = gaussian(),
259- # log_gdp_std ~ 0 + african_status + rugged_std_centered)
259+ # log_gdp_std ~ 0 + cont + rugged_std_centered)
260+
260261
261262```
262263
@@ -266,9 +267,13 @@ b8.1 <- brm(data = rugged_clean,
266267
267268##### 📈 μ heatmap
268269
270+ ::: panel-tabset
271+
272+ ###### Plot 1
273+
269274``` {r}
270275simCov <-
271- crossing(african_status = c("african ", "not african "),
276+ crossing(cont = c("African ", "Not African "),
272277 rugged_std = seq(from = -0.2, to = 1.2, length.out = 30)) %>%
273278 mutate(rugged_std_centered = rugged_std - mean(rugged_clean$rugged_std))
274279
@@ -278,21 +283,25 @@ fitted(b8.1,
278283 data.frame() %>%
279284 pivot_longer(everything()) %>%
280285 bind_cols(expand_grid(draws = 1:4000, simCov)) %>%
281- ggplot(aes(x = rugged_std_centered, y = value, fill = african_status , color = african_status ))+
286+ ggplot(aes(x = rugged_std_centered, y = value, fill = cont , color = cont ))+
282287 stat_lineribbon(.width = seq(from = .03, to = .99, by =.03),
283288 alpha = .1, size = 0) +
284289 geom_point(data = rugged_clean, aes(x = rugged_std_centered, y = log_gdp_std,
285- fill = african_status , color = african_status ))+
290+ fill = cont , color = cont ))+
286291 theme_minimal() +
287292 labs(y = "log GDP (as proportion of mean)") +
288293 scale_x_continuous("Ruggedness (0 = minimum ruggedness, 100 = maximum ruggedness)",
289294 breaks = at,
290295 labels = round(at + mean(rugged_clean$rugged_std), 1) * 100,
291- limits = c(floor(min(at) * 10) / 10, ceiling(max(at) * 10) / 10))
296+ limits = c(floor(min(at) * 10) / 10, ceiling(max(at) * 10) / 10))+
297+ theme(legend.background = element_blank(),
298+ legend.direction = "horizontal",
299+ legend.position = c(.67, .93),
300+ legend.title = element_blank())
292301
293302```
294303
295- ##### 📈 Alt μ heatmap
304+ ###### plot 2
296305
297306``` {r}
298307fitted(b8.1,
@@ -308,7 +317,7 @@ fitted(b8.1,
308317 geom_point(data = rugged_clean,
309318 aes(x = rugged_std_centered, y = log_gdp_std),
310319 shape = 21, color = "white", fill = "black", size = 2, alpha = 0.8) +
311- facet_wrap(~ african_status , labeller = label_both) +
320+ facet_wrap(~ cont , labeller = label_both) +
312321 theme_void() +
313322 theme(
314323 panel.background = element_rect(fill = "black"),
@@ -325,7 +334,7 @@ fitted(b8.1,
325334 labels = round(at + mean(rugged_clean$rugged_std), 1) * 100) +
326335 guides(fill = "none")
327336```
328-
337+ :::
329338
330339##### 🎛 Parameters
331340
@@ -335,8 +344,8 @@ fitted(b8.1,
335344
336345as_tibble(b8.1) %>%
337346 rename("Ruggedness" = b_rugged_std_centered,
338- "African" = b_african_statusafrican ,
339- "Non-African" = b_african_statusnotafrican ) %>%
347+ "African" = b_contAfrican ,
348+ "Non-African" = b_contNotAfrican ) %>%
340349 dplyr::select(c(`Ruggedness`, `African`, `Non-African`)) %>%
341350 pivot_longer(cols = everything(),
342351 names_to = "Covariate",
@@ -353,14 +362,18 @@ as_tibble(b8.1) %>%
353362
354363```
355364
365+ :::
366+
367+ Adding Africa as an index covariate didn't get that reversal of slopes that we saw in our first plot. But when we compare this model to not having the Africa index covariate with WAIC, its clearly superior. So the Africa variable is clearly picking up some important association in the data. African countries have a lower average Log GDP regardless of their ruggedness and that's what our African index covariate supports.
368+
369+
356370
357371``` {r}
358372#| fig-width: 10
359373#| fig-height: 2
360374
361375b8.0 <- add_criterion(b8.0, criterion = "waic")
362376b8.1 <- add_criterion(b8.1, criterion = "waic")
363- b8.1$criteria$waic
364377
365378w <- loo_compare(b8.0, b8.1, criterion = "waic")
366379
@@ -374,7 +387,7 @@ w[, 7:8] %>%
374387 xmax = waic + se_waic)) +
375388 geom_pointrange(color = carto_pal(7, "BurgYl")[7],
376389 fill = carto_pal(7, "BurgYl")[5], shape = 21) +
377- labs(title = "My custom WAIC plot",
390+ labs(title = "WAIC model comparison plot",
378391 x = NULL, y = NULL) +
379392 theme(axis.ticks.y = element_blank())+
380393 theme_minimal()
@@ -386,7 +399,178 @@ loo_compare(b8.0, b8.1, criterion = "loo") %>%
386399 print(simplify = F)
387400```
388401
389- $$ \eta_n = \sum_{i = 1}^K b_i x_{ni} $$
402+ #### Adding an Interaction does work
403+
404+ How can we we recover the difference in slope that we saw at the beginning of this section? We need a proper interaction effect. This just means we make the slope conditional on whether it's part of Africa or not.
405+
406+ Just above we modeled
407+
408+ $$ \mu_i = \alpha_\text{Africa [i]} + \beta_1(\text{rugged}_i - \overline{rugged}) $$
409+
410+ But now we're going to make an index for $\beta$ as well.
411+
412+ $$ \mu_i = \alpha_\text{Africa [i]} + \beta_\text{Africa[i]}(\text{rugged}_i - \overline{rugged}) $$
413+
414+ ``` {r}
415+ b8.2 <- brm(data = rugged_clean,
416+ family = gaussian(),
417+ bf(log_gdp_std ~ 0 + a + b * rugged_std_centered,
418+ a ~ 0 + cont,
419+ b ~ 0 + cont,
420+ nl = TRUE),
421+ prior = c(
422+ prior(normal(1, 0.1), class = b, nlpar = a, coef = contAfrican),
423+ prior(normal(1, 0.1), class = b, nlpar = a, coef = contNotAfrican),
424+ prior(normal(0, 0.3), class = b, nlpar = b, coef = contAfrican),
425+ prior(normal(0, 0.3), class = b, nlpar = b, coef = contNotAfrican),
426+ prior(exponential(1), class = sigma)
427+ ),
428+ iter = 2000, warmup = 1000, cores = 4, seed = 5,
429+ backend = "cmdstanr", silent = 2, file = "fits/b08.2.1")
430+
431+ # get_prior(data = rugged_clean,
432+ # family = gaussian(),
433+ # bf(log_gdp_std ~ 0 + a + b * rugged_std_centered,
434+ # a ~ 0 + cont,
435+ # b ~ 0 + cont,
436+ # nl = TRUE))
437+ ```
438+
439+ ::: panel-tabset
440+
441+ ##### 📈 μ heatmap
442+
443+ ::: panel-tabset
444+
445+ ###### Plot 1
446+
447+ ``` {r}
448+ simCov <-
449+ crossing(cont = c("African", "Not African"),
450+ rugged_std = seq(from = -0.2, to = 1.2, length.out = 30)) %>%
451+ mutate(rugged_std_centered = rugged_std - mean(rugged_clean$rugged_std))
452+
453+ fitted(b8.2,
454+ newdata = simCov,
455+ summary = F) %>%
456+ data.frame() %>%
457+ pivot_longer(everything()) %>%
458+ bind_cols(expand_grid(draws = 1:4000, simCov)) %>%
459+ ggplot(aes(x = rugged_std_centered, y = value, fill = cont, color = cont))+
460+ stat_lineribbon(.width = seq(from = .03, to = .99, by =.03),
461+ alpha = .1, size = 0) +
462+ geom_point(data = rugged_clean, aes(x = rugged_std_centered, y = log_gdp_std,
463+ fill = cont, color = cont))+
464+ theme_minimal() +
465+ labs(y = "log GDP (as proportion of mean)") +
466+ scale_x_continuous("Ruggedness (0 = minimum ruggedness, 100 = maximum ruggedness)",
467+ breaks = at,
468+ labels = round(at + mean(rugged_clean$rugged_std), 1) * 100,
469+ limits = c(floor(min(at) * 10) / 10, ceiling(max(at) * 10) / 10))+
470+ theme(legend.background = element_blank(),
471+ legend.direction = "horizontal",
472+ legend.position = c(.67, .93),
473+ legend.title = element_blank())
474+
475+ ```
476+
477+
478+
479+
480+
481+ ###### plot 2
482+
483+ ``` {r}
484+ fitted(b8.2,
485+ newdata = simCov,
486+ summary = F) %>%
487+ data.frame() %>%
488+ pivot_longer(everything()) %>%
489+ bind_cols(expand_grid(draws = 1:4000, simCov)) %>%
490+ ggplot(aes(x = rugged_std_centered, y = value)) +
491+ stat_density_2d(aes(fill = after_stat(ndensity)),
492+ geom = "raster", contour = FALSE) +
493+ scale_fill_viridis_c(option = "magma") +
494+ geom_point(data = rugged_clean,
495+ aes(x = rugged_std_centered, y = log_gdp_std),
496+ shape = 21, color = "white", fill = "black", size = 2, alpha = 0.8) +
497+ facet_wrap(~ cont, labeller = label_both) +
498+ theme_void() +
499+ theme(
500+ panel.background = element_rect(fill = "black"),
501+ plot.background = element_rect(fill = "black"),
502+ strip.text = element_text(color = "white", size = 12),
503+ axis.text = element_text(color = "white"),
504+ axis.title.x = element_text(color = "white"),
505+ axis.title.y = element_text(color = "white", angle = 90, vjust = 0.5), # Rotated y-axis title
506+ plot.title = element_text(color = "white")
507+ ) +
508+ labs(y = "log GDP (as proportion of mean)") +
509+ scale_x_continuous("Ruggedness (0 = minimum ruggedness, 100 = maximum ruggedness)",
510+ breaks = at,
511+ labels = round(at + mean(rugged_clean$rugged_std), 1) * 100) +
512+ guides(fill = "none")
513+ ```
514+
515+ :::
516+
517+ ##### 🎛 Parameters
518+
519+ ``` {r}
520+ #| fig-width: 10
521+ #| fig-height: 2
522+
523+ as_tibble(b8.2) %>%
524+ rename("Intercept African" = b_a_contAfrican,
525+ "Intercept Non-African" = b_a_contNotAfrican,
526+ "Ruggedness African" = b_b_contAfrican,
527+ "Ruggedness Non-African" = b_b_contNotAfrican,
528+ ) %>%
529+ dplyr::select(c(`Intercept African`, `Intercept Non-African`, `Ruggedness African`, `Ruggedness Non-African`)) %>%
530+ pivot_longer(cols = everything(),
531+ names_to = "Covariate",
532+ values_to = "Effect") %>%
533+ ggplot(aes(x = `Effect`, y = reorder(Covariate, `Effect`))) +
534+ stat_halfeye(point_interval = median_qi, .width = .95,
535+ fill = "firebrick4") +
536+ labs(x = "Effect on Log GDP per capita",
537+ y = NULL) +
538+ theme_bw() +
539+ theme(axis.text.y = element_text(hjust = 0),
540+ axis.ticks.y = element_blank(),
541+ panel.grid = element_blank())
542+
543+ ```
544+
545+ :::
546+
547+ ``` {r}
548+ #| fig-width: 10
549+ #| fig-height: 2
550+
551+ b8.2 <- add_criterion(b8.2, criterion = "loo")
552+ b8.2 <- add_criterion(b8.2, criterion = "waic")
553+
554+ loo_compare(b8.0, b8.1, b8.2, criterion = "loo") %>%
555+ print(simplify = F)
556+
557+
558+
559+ w <- loo_compare(b8.0, b8.1, b8.2, criterion = "waic")
560+
561+ w[, 7:8] %>%
562+ data.frame() %>%
563+ rownames_to_column("model_name") %>%
564+ mutate(model_name = fct_reorder(model_name, waic, .desc = T)) %>%
565+
566+ ggplot(aes(x = waic, y = model_name,
567+ xmin = waic - se_waic,
568+ xmax = waic + se_waic)) +
569+ geom_pointrange(color = carto_pal(7, "BurgYl")[7],
570+ fill = carto_pal(7, "BurgYl")[5], shape = 21) +
571+ labs(title = "WAIC model comparison plot",
572+ x = NULL, y = NULL) +
573+ theme(axis.ticks.y = element_blank())+
574+ theme_minimal()
575+ ```
390576
391- $$ \eta_n = b_1 \exp(b_2 x_n) $$
392- $$ cum_{AY, dev} \sim N(\mu_{AY, dev}, \sigma) \mu_{AY, dev} = ult_{AY} \left(1 - \exp\left(- \left( \frac{dev}{\theta} \right)^\omega \right) \right) $$
0 commit comments