kappa_hat <- lam0 / tau2
resultados <- vi_df |>
mutate(
omega_i = vi / (vi + kappa_hat),
lam_cred = omega_i * Fbar_v + (1 - omega_i) * lam0
)
# Dados de 2014 para validação
val_2014 <- bs_data |>
filter(Ano == "2014", faixa != "[0, 18)") |>
select(faixa, v_2014 = vit, N_obs_2014 = Nit)
# Óbitos esperados pelas três tábuas em 2014
tabua_2014 <- fundo_long |>
filter(Ano == "2014", Idade >= 18) |>
left_join(
data.frame(Idade = brems$idade[1:116], qx_br = brems$brems2021sb.m[1:116]),
by = "Idade"
) |>
left_join(
data.frame(Idade = at2000$idade, qx_at = at2000$at2000.m),
by = "Idade"
) |>
left_join(
data.frame(Idade = pub2010_full$idade, qx_pub = pub2010_full$qx),
by = "Idade"
) |>
mutate(
faixa = cut(Idade, breaks = intervalos_num, right = FALSE, labels = labels_fx),
D_br = Expostos * qx_br,
D_at = Expostos * qx_at,
D_pub = Expostos * replace_na(qx_pub, 0)
) |>
filter(!is.na(faixa)) |>
group_by(faixa) |>
summarise(
D_br = sum(D_br, na.rm = TRUE),
D_at = sum(D_at, na.rm = TRUE),
D_pub = sum(D_pub, na.rm = TRUE),
.groups = "drop"
) |>
rename(D_tab = D_br) # manter compatibilidade: D_tab = BR-EMS
# Tabela unificada: credibilidade + previsão + validação + três tábuas
previsao <- resultados |>
left_join(val_2014, by = "faixa") |>
left_join(tabua_2014, by = "faixa") |>
mutate(
N_prev = v_2014 * lam_cred,
erro_bs = if_else(N_obs_2014 > 0, (N_prev - N_obs_2014) / N_obs_2014 * 100, NA_real_),
erro_br = if_else(N_obs_2014 > 0, (D_tab - N_obs_2014) / N_obs_2014 * 100, NA_real_),
erro_at = if_else(N_obs_2014 > 0, (D_at - N_obs_2014) / N_obs_2014 * 100, NA_real_),
erro_pub = if_else(N_obs_2014 > 0 & D_pub > 0,
(D_pub - N_obs_2014) / N_obs_2014 * 100, NA_real_)
)
# Helper: cor verde na célula com menor erro absoluto entre múltiplas colunas
previsao |>
select(faixa, vi, Fbar_v, omega_i, lam_cred,
v_2014, N_prev, N_obs_2014,
D_tab, D_at, D_pub,
erro_bs, erro_br, erro_at, erro_pub) |>
bind_rows(
tibble(
faixa = "Total",
vi = sum(previsao$vi),
Fbar_v = NA_real_,
omega_i = NA_real_,
lam_cred = NA_real_,
v_2014 = sum(previsao$v_2014),
N_prev = sum(previsao$N_prev),
N_obs_2014 = sum(previsao$N_obs_2014),
D_tab = sum(previsao$D_tab),
D_at = sum(previsao$D_at),
D_pub = sum(previsao$D_pub),
erro_bs = (sum(previsao$N_prev) - sum(previsao$N_obs_2014)) /
sum(previsao$N_obs_2014) * 100,
erro_br = (sum(previsao$D_tab) - sum(previsao$N_obs_2014)) /
sum(previsao$N_obs_2014) * 100,
erro_at = (sum(previsao$D_at) - sum(previsao$N_obs_2014)) /
sum(previsao$N_obs_2014) * 100,
erro_pub = (sum(previsao$D_pub) - sum(previsao$N_obs_2014)) /
sum(previsao$N_obs_2014) * 100
)
) |>
gt() |>
tab_header(
title = "Bühlmann-Straub: estimação e validação (2014)",
subtitle = md(sprintf(
"$\\hat{\\lambda}_0 = %.5f$ | $\\hat{\\tau}^2 = %.6f$ | $\\hat{\\kappa} = %.2f$",
lam0, tau2, kappa_hat
))
) |>
cols_label(
faixa = "Grupo",
vi = md("$v_i$"),
Fbar_v = md("$\\bar{F}_i^v$"),
omega_i = md("$\\hat{\\omega}_i$"),
lam_cred = md("$\\hat{\\lambda}_i^H$"),
v_2014 = md("$v_{i,2014}$"),
N_prev = md("$\\hat{N}_{i,2014}$ (BS)"),
N_obs_2014 = md("$N_i^{\\text{obs}}$"),
D_tab = md("$\\hat{D}^{\\text{BR-EMS}}$"),
D_at = md("$\\hat{D}^{\\text{AT-2000}}$"),
D_pub = md("$\\hat{D}^{\\text{Pub-2010}}$"),
erro_bs = "Erro BS (%)",
erro_br = "Erro BR-EMS (%)",
erro_at = "Erro AT-2000 (%)",
erro_pub = "Erro Pub-2010 (%)"
) |>
tab_spanner(label = "Ajuste 2012--2013",
columns = c(vi, Fbar_v, omega_i, lam_cred)) |>
tab_spanner(label = "Validação 2014",
columns = c(v_2014, N_prev, N_obs_2014)) |>
tab_spanner(label = "Tábuas de referência",
columns = c(D_tab, D_at, D_pub)) |>
tab_spanner(label = "Erros de previsão (%)",
columns = c(erro_bs, erro_br, erro_at, erro_pub)) |>
fmt_number(columns = vi, decimals = 0) |>
fmt_number(columns = c(Fbar_v, lam_cred), decimals = 6) |>
fmt_number(columns = omega_i, decimals = 4) |>
fmt_number(columns = v_2014, decimals = 0) |>
fmt_number(columns = c(N_prev, N_obs_2014, D_tab, D_at, D_pub), decimals = 1) |>
fmt_number(columns = c(erro_bs, erro_br, erro_at, erro_pub), decimals = 1) |>
sub_missing(missing_text = "—") |>
tab_style(
style = list(cell_fill("#EBF5FB"), cell_text(weight = "bold")),
locations = cells_body(rows = faixa == "Total")
) |>
# Verde: BS vs. todas as tábuas
tab_style(
style = cell_fill("#D5F5E3"),
locations = cells_body(
columns = erro_bs,
rows = !is.na(erro_bs) &
abs(erro_bs) < abs(replace_na(erro_br, Inf)) &
abs(erro_bs) < abs(replace_na(erro_at, Inf)) &
abs(erro_bs) < abs(replace_na(erro_pub, Inf))
)
) |>
# Verde: melhor tábua por faixa (lógica inline — evita problema de tamanho de vetor)
tab_style(
style = cell_fill("#D5F5E3"),
locations = cells_body(
columns = erro_br,
rows = !is.na(erro_br) & faixa != "Total" &
abs(erro_br) <= abs(replace_na(erro_at, Inf)) &
abs(erro_br) <= abs(replace_na(erro_pub, Inf))
)
) |>
tab_style(
style = cell_fill("#D5F5E3"),
locations = cells_body(
columns = erro_at,
rows = !is.na(erro_at) & faixa != "Total" &
abs(erro_at) < abs(replace_na(erro_br, Inf)) &
abs(erro_at) <= abs(replace_na(erro_pub, Inf))
)
) |>
tab_style(
style = cell_fill("#D5F5E3"),
locations = cells_body(
columns = erro_pub,
rows = !is.na(erro_pub) & faixa != "Total" &
abs(erro_pub) < abs(replace_na(erro_br, Inf)) &
abs(erro_pub) < abs(replace_na(erro_at, Inf))
)
) |>
tab_options(table.font.size = 11)