Simulações

As simulações rodam no navegador, em Observable JS (OJS), que o Quarto suporta sem servidor. Cada simulação fica numa seção ## Simulação da aula, dentro de abas: a aba “Interativo” tem os controles e o gráfico, e a aba “Em R” mostra o código equivalente, sem executar.

Exemplo: viés de colisor

Suponha que talento e beleza sejam independentes na população, e que só chegue a Hollywood quem tem a soma dos dois acima de um corte. Entre os selecionados, as duas características passam a ter correlação negativa, embora não haja relação nenhuma entre elas (Elwert e Winship 2014; Cunningham 2021).

Código
set.seed(42)
n <- 1500; corte <- 1
talento <- rnorm(n); beleza <- rnorm(n)
selecionado <- talento + beleza > corte
cor(talento, beleza)                                 # perto de zero
cor(talento[selecionado], beleza[selecionado])       # negativa

Como escrever uma simulação

  1. Importe os utilitários do template no primeiro bloco OJS da página. O caminho começa com /, que o Quarto resolve a partir da raiz do projeto:

    import {scheme, palette, plotStyle, rng, corr, mean, sd, ols, fmt} from "/_extensions/felipelmc/course-notes/ojs/notes.js"
    mode = scheme()
    pal = palette(mode)

    scheme() reage ao botão de tema, e palette(mode) devolve as cores do tema atual (pal.accent, pal.ink3, pal.ramp…). Como pal depende de mode, os gráficos mudam de cor quando o leitor troca o tema.

  2. Use rng(semente) para sortear. Com semente fixa, mexer num controle não embaralha os dados, e o leitor vê só o efeito do parâmetro. Para um novo sorteio, some um botão:

    viewof sorteio = Inputs.button("Novo sorteio", {value: 1, reduce: (v) => v + 1})
  3. Envolva controles, gráfico e resultado num bloco ::: cn-sim, que desenha o cartão.

  4. Mantenha o custo baixo: até uns 5 mil pontos por gráfico e laços simples. Para algo pesado (um modelo multinível, por exemplo), rode no R, agregue e passe o resultado para o OJS com ojs_define():

    ```{r}
    resumo <- dados |> dplyr::count(uf, voto)
    ojs_define(resumo = resumo)
    ```
    ```{ojs}
    Plot.barY(transpose(resumo), {x: "uf", y: "n"})
    ```
  5. Para dados pequenos (um CSV de algumas centenas de linhas), use FileAttachment("interativo/arquivo.csv").csv({typed: true}). Só são publicadas as pastas dados-sim/ (na raiz) e trabalhos/<slug>/interativo/; os dados brutos em dados/ ficam fora do site. Publique apenas agregados.

  6. Na aba “Em R”, o bloco leva #| eval: false: mostra o código sem executar, então a página não precisa de dados nem de congelamento.

  7. Simulações e textos preparados com auxílio de IA seguem a mesma regra das explicações: o texto que apresenta a simulação vai numa caixa nota-ia aberta, antes das abas.

    ::: {.nota-ia collapse="false" title="Simulação e texto preparados com auxílio do Claude"}
    O que a simulação mostra e como ler o gráfico.
    :::
  8. Escreva a simulação no próprio arquivo da aula, e não num arquivo incluído com include. O congelamento compara só o texto do arquivo da aula: uma simulação num arquivo à parte poderia mudar sem que a página fosse renderizada de novo.

Cunningham, Scott. 2021. Causal Inference: The Mixtape. Yale University Press. https://mixtape.scunning.com/.
Elwert, Felix, e Christopher Winship. 2014. “Endogenous Selection Bias: The Problem of Conditioning on a Collider Variable”. Annual Review of Sociology 40: 31–53. https://doi.org/10.1146/annurev-soc-071913-043455.