1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
use greeners::{CovarianceType, FixedEffects, OLS};
use ndarray::{Array1, Array2, Axis};
fn main() -> Result<(), Box<dyn std::error::Error>> {
// Simulando 2 Empresas (Entities), 5 Anos cada.
// Modelo: y = alpha_i + 2.0 * x + erro
// Empresa 1: Alpha = 10 (Alta performance fixa)
// Empresa 2: Alpha = -10 (Baixa performance fixa)
// X aumenta com o tempo
let x_vals = vec![
1.0, 2.0, 3.0, 4.0, 5.0, // Emp 1
1.0, 2.0, 3.0, 4.0, 5.0, // Emp 2
];
// Y = Alpha + 2*X
let y_vals = vec![
12.0, 14.0, 16.0, 18.0, 20.0, // Emp 1 (10 + 2*x)
-8.0, -6.0, -4.0, -2.0, 0.0, // Emp 2 (-10 + 2*x)
];
let ids = vec![1, 1, 1, 1, 1, 2, 2, 2, 2, 2];
let y = Array1::from(y_vals);
let x_col = Array1::from(x_vals);
// Transforma X em Matriz Nx1
let x = x_col.view().insert_axis(Axis(1)).to_owned();
println!("Verdadeiro Beta (Inclinação): 2.0");
println!("Diferença de Nível (Efeito Fixo): Empresa 1 é 20 unidades maior que Empresa 2");
// 1. Rodar Pooled OLS (Ignora a empresa)
// O Pooled OLS vai tentar traçar uma reta que passa no meio das duas nuvens de pontos.
// Provavelmente vai achar que X não explica muito, ou achar um Beta estranho se X fosse correlacionado com Alpha.
// Precisamos adicionar constante manualmente para o Pooled
let ones = Array2::ones((10, 1));
let x_pooled = ndarray::concatenate(Axis(1), &[ones.view(), x.view()])?;
let pooled_res = OLS::fit(&y, &x_pooled, CovarianceType::NonRobust)?;
println!("\n--- Pooled OLS (Naive) ---");
println!("R2: {:.4}", pooled_res.r_squared);
// O R2 será baixo porque a variância "Entre Empresas" (Between) é enorme e não explicada por X.
// 2. Rodar Fixed Effects
// Não passamos constante! O FE remove a constante global e os alphas.
let fe_res = FixedEffects::fit(&y, &x, &ids)?;
println!("\n--- Fixed Effects (Within) ---");
println!("Beta Estimado: {:.4}", fe_res.params[0]);
println!("{}", fe_res);
println!(
"Note como o R2 ('Within') deve ser 1.0 ou muito próximo, pois limpamos o efeito fixo."
);
Ok(())
}