Lendo os dados

rm(list = ls())
getwd()
## [1] "/Users/eduardorodrigues/Google Drive/Estudos/Mestrado_CD_Aluno.Especial/03 - Métodos Inferenciais Avançados/Trabalhos/MIAPL_TrabalhoFinal"
source_linux = '/home/eduandrade/Documents/Estudos/Métodos Inferenciais Avançados/TrabalhoFinal'
source_windows = 'C:/Users/55619/Google Drive/Estudos/Mestrado_CD_Aluno.Especial/03 - Métodos Inferenciais Avançados/Trabalhos/MIAPL_TrabalhoFinal'
source_mac = '/Users/eduardorodrigues/Google Drive/Estudos/Mestrado_CD_Aluno.Especial/03 - Métodos Inferenciais Avançados/Trabalhos/MIAPL_TrabalhoFinal'
#setwd(source_linux)
setwd(source_mac)
base_respostas = read.csv('Base TCU - Indicadores de Gestão - Base de respostas.csv',
                          encoding='UTF-8')
base_respostas %>%
  select(idBase, iGG, iGovTI, iGovPessoas, iGovPub, iGovContrat) %>%
  head %>%
  kable("html") %>%
  kable_styling(bootstrap_options = c("striped", "condensed", "hover"),
                                      full_width = FALSE, position = "left")
idBase iGG iGovTI iGovPessoas iGovPub iGovContrat
1 0.590290 0.778303 0.471154 0.668102 0.750269
3 0.586405 0.650355 0.536626 0.659846 0.720297
4 0.621258 0.726745 0.616739 0.754760 0.748290
5 0.480198 0.512551 0.465240 0.408306 0.406778
6 0.637614 0.559311 0.569063 0.667989 0.771531
8 0.456855 0.600703 0.461752 0.548451 0.411765
dim(base_respostas)
## [1] 498  71

O relatório do TCU (que é de 2017) informa que 488 entidades responderam (parágrafo 6 do relatório completo. No banco de dados, há respostas de 498 entidades. Essa diferença provavelmene se explica por pegarmos o banco de dados de 2018.

base_respondentes = read.csv('Base TCU - Indicadores de Gestão - Base de respondentes.csv',
                             encoding = 'UTF-8')

base_respondentes %>%
  head %>%
  kable("html") %>%
  kable_styling(bootstrap_options = c("striped", "condensed", "hover"),
                                      full_width = FALSE, position = "left")
idBase2018 NomeOrg Sigla Status Tipo Segmento Classificação.GAB.TM
1 Câmara dos Deputados CD 4.Submetido Casa legislativa LEG
2 Fundo Rotativo da Câmara dos Deputados FRCD 0.Excluído Fundo Fundo
3 Senado Federal SF 4.Submetido Casa legislativa LEG
4 Tribunal de Contas da União TCU 4.Submetido Tribunal LEG
5 Supremo Tribunal Federal STF 4.Submetido Tribunal JUD
6 Superior Tribunal de Justiça STJ 4.Submetido Tribunal JUD
dim(base_respondentes)
## [1] 710   7

Juntando as Bases

As bases são juntadas pelo id das instituições. As instituições que não possuem dados associados são descartadas. Assim, a número de observações é igual ao número de linhas da base de respostas.

base = merge(y=base_respostas, x=base_respondentes, by.y='idBase', by.x='idBase2018')
dim(base)
## [1] 498  77

Sumário de Estatísticas do Índice Geral de Governança (iGG) por Tipo de Organização

group_by(base, Tipo) %>%
  summarise(
    count = n(),
    mean = mean(iGG, na.rm = TRUE),
    sd = sd(iGG, na.rm = TRUE),
    median = median(iGG, na.rm = TRUE),
    IQR = IQR(iGG, na.rm = TRUE)
  ) %>%
  kable("html") %>%
  kable_styling(bootstrap_options = c("striped", "condensed", "hover"),
                                      full_width = FALSE, position = "left")
Tipo count mean sd median IQR
Autarquia 39 0.4570212 0.1816491 0.4497590 0.2048745
Banco 12 0.7451222 0.1124296 0.7403155 0.1006320
Casa legislativa 2 0.5883475 0.0027471 0.5883475 0.0019425
Conselho Profissional 26 0.2592457 0.2056409 0.1791485 0.2395232
Estadual/Distrital 3 0.4263983 0.0933856 0.4790330 0.0815050
Estatal 66 0.4790044 0.2012856 0.4926390 0.3345253
Funções Essenciais à Justiça 6 0.4643428 0.1265282 0.4296890 0.1431298
Fundação 15 0.3696339 0.1756169 0.3750150 0.2325355
Fundo 5 0.5458512 0.3517785 0.5966980 0.5728560
Instituição de ensino 117 0.3614831 0.1451389 0.3414580 0.1691670
Militar 10 0.6742002 0.1000250 0.6809690 0.0832170
Ministério 22 0.4371676 0.1601572 0.4121355 0.1572597
Órgão executivo (Adm. Direta) 19 0.4213459 0.1540376 0.4162340 0.2021510
Paraestatal 16 0.4531033 0.1861674 0.4314545 0.2106538
Tribunal 91 0.4492277 0.1154638 0.4376410 0.1374395
Unidade de Saúde 49 0.4001195 0.1817013 0.4004690 0.2062560

Alguns tipos de instituição possuem quantidade de amostras muito baixas e podem não representar a população a que pertencem (exceto aqueles grupos cuja população seja pequeno, tal como as Casas Legislativa Federais). Dessarte, decidiu-se por usar apenas os tipos que tenham mais de 30 amostras.

freq_tipo = data.frame(table(base$Tipo))

tipos_entidades = freq_tipo %>%
  filter(Freq >= 30) %>%
  select(Var1)

base_interesse = base %>%
  filter(Tipo %in% tipos_entidades$Var1)

base_interesse %>%
  select(NomeOrg, Tipo, iGG, iGovTI, iGovPessoas, iGovPub, iGovContrat) %>%
  head %>%
  kable("html") %>%
  kable_styling(bootstrap_options = c("striped", "condensed", "hover"),
                                      full_width = FALSE, position = "left")
NomeOrg Tipo iGG iGovTI iGovPessoas iGovPub iGovContrat
Tribunal de Contas da União Tribunal 0.621258 0.726745 0.616739 0.754760 0.748290
Supremo Tribunal Federal Tribunal 0.480198 0.512551 0.465240 0.408306 0.406778
Superior Tribunal de Justiça Tribunal 0.637614 0.559311 0.569063 0.667989 0.771531
Tribunal Regional Federal da 1a. Região Tribunal 0.456855 0.600703 0.461752 0.548451 0.411765
Tribunal Regional Federal da 2a. Região Tribunal 0.306276 0.398180 0.235507 0.286709 0.433841
Tribunal Regional Federal da 3a. Região Tribunal 0.402711 0.482306 0.431078 0.470983 0.452818
dim(base_interesse)
## [1] 362  77

Com essa restrição, diminuímos a número total de entidade de 498 para 362.

Renomeando nomes longos de tipos de entidades

As entidades Instituições de ensino e Unidades de Saúde possuem nomes muito longos e atrapalham algumas visualizações. Esse nomes serão alterados para Ensino e Saúde respectivamente.

levels(base_interesse$Tipo) <- c(levels(base_interesse$Tipo), "Ensino", "Saúde")
base_interesse$Tipo[base_interesse$Tipo == "Instituição de ensino"] = "Ensino"
base_interesse$Tipo[base_interesse$Tipo == "Unidade de Saúde"] = "Saúde"

Sumário de Estatísticas para a Base de Interesse

group_by(base_interesse, Tipo) %>%
  summarise(
    count = n(),
    mean = mean(iGG, na.rm = TRUE),
    sd = sd(iGG, na.rm = TRUE),
    median = median(iGG, na.rm = TRUE),
    IQR = IQR(iGG, na.rm = TRUE)
  ) %>%
  kable("html") %>%
  kable_styling(bootstrap_options = c("striped", "condensed", "hover"),
                                      full_width = FALSE, position = "left")
Tipo count mean sd median IQR
Autarquia 39 0.4570212 0.1816491 0.449759 0.2048745
Estatal 66 0.4790044 0.2012856 0.492639 0.3345253
Tribunal 91 0.4492277 0.1154638 0.437641 0.1374395
Ensino 117 0.3614831 0.1451389 0.341458 0.1691670
Saúde 49 0.4001195 0.1817013 0.400469 0.2062560

As mesmas estatísticas para a base de interesse inteira

base_interesse %>%
  summarise(
    count = n(),
    mean = mean(iGG, na.rm = TRUE),
    sd = sd(iGG, na.rm = TRUE),
    median = median(iGG, na.rm = TRUE),
    IQR = IQR(iGG, na.rm = TRUE)
  ) %>%
  kable("html") %>%
  kable_styling(bootstrap_options = c("striped", "condensed", "hover"),
                                      full_width = FALSE, position = "left")
count mean sd median IQR
362 0.4204895 0.1655718 0.406281 0.2071372

Boxplot para os Tipos de Entidades de Interesse

ggplot(base_interesse, aes(x=Tipo, y=iGG)) + 
  geom_boxplot(fill="gray")+
  labs(title="iGG por Tipo", x="Tipo", y = "iGG")+
  theme_classic()

Gráfico de Linha com a Média e Erro Padrão

ggline(base_interesse, x = "Tipo", y = "iGG", 
       add = c("mean_se"), 
       color = "steelblue",
       point.color = "red",
       ylab = "iGG", xlab = "Tipo Entidade")

Verificação se as Distribuições entre os Grupos são Estatisticamente Identicas

Inspeção Visual para Ver Se Podemos Usar Anova

Verificaremos se as distribuições dentro dos grupos são normais.

hist_autarquia = ggplot(base_interesse[base_interesse$Tipo == "Autarquia", ],
       aes(x=iGG, y = ..density..)) +
  geom_histogram(alpha = 0.3, bins=20) +
  geom_density(size = 0.5, color = "red") +
  ggtitle("iGG - Autarquias") +
  ylab("")

hist_estatal = ggplot(base_interesse[base_interesse$Tipo == "Estatal", ],
       aes(x=iGG, y = ..density..)) +
  geom_histogram(alpha = 0.3, bins=20) +
  geom_density(size = 0.5, color = "red") +
  ggtitle("iGG - Estatais") +
  ylab("")

hist_tribunal = ggplot(base_interesse[base_interesse$Tipo == "Tribunal", ],
       aes(x=iGG, y = ..density..)) +
  geom_histogram(alpha = 0.3, bins=20) +
  geom_density(size = 0.5, color = "red") +
  ggtitle("iGG - Tribunais") +
  ylab("")

hist_saude = ggplot(base_interesse[base_interesse$Tipo == "Saúde", ],
       aes(x=iGG, y = ..density..)) +
  geom_histogram(alpha = 0.3, bins=20) +
  geom_density(size = 0.5, color = "red") +
  ggtitle("iGG - Saúde") +
  ylab("")

hist_ensino = ggplot(base_interesse[base_interesse$Tipo == "Ensino", ],
       aes(x=iGG, y = ..density..)) +
  geom_histogram(alpha = 0.3, bins=20) +
  geom_density(size = 0.5, color = "red") +
  ggtitle("iGG - Ensino") +
  ylab("")

ggarrange(hist_autarquia, hist_estatal, hist_ensino,
          hist_tribunal, hist_saude,
          ncol = 3, nrow = 2)

Nem todas parecem ser normais. Vamos executar um teste estatístico para verificar numericamente.

Teste de Shapiro-Wilk para Verificar Normalidade dentro dos Grupos

# p-value = 0.8893, a distribuição é normal
shapiro.test(base_interesse[base_interesse$Tipo == "Autarquia", ]$iGG)
## 
##  Shapiro-Wilk normality test
## 
## data:  base_interesse[base_interesse$Tipo == "Autarquia", ]$iGG
## W = 0.98558, p-value = 0.8893
# p-value = 0.1621, a distribuiçãi é normal
shapiro.test(base_interesse[base_interesse$Tipo == "Estatal", ]$iGG)
## 
##  Shapiro-Wilk normality test
## 
## data:  base_interesse[base_interesse$Tipo == "Estatal", ]$iGG
## W = 0.97314, p-value = 0.1621
# p-value = 0.003394, a distribuição não é normal
shapiro.test(base_interesse[base_interesse$Tipo == "Tribunal", ]$iGG)
## 
##  Shapiro-Wilk normality test
## 
## data:  base_interesse[base_interesse$Tipo == "Tribunal", ]$iGG
## W = 0.95533, p-value = 0.003394
# p-value = 0.01707, a distribuição não é normal
shapiro.test(base_interesse[base_interesse$Tipo == "Saúde", ]$iGG)
## 
##  Shapiro-Wilk normality test
## 
## data:  base_interesse[base_interesse$Tipo == "Saúde", ]$iGG
## W = 0.9416, p-value = 0.01707
# p-value = 0.00777, a distribuição não é normal
shapiro.test(base_interesse[base_interesse$Tipo == "Ensino", ]$iGG)
## 
##  Shapiro-Wilk normality test
## 
## data:  base_interesse[base_interesse$Tipo == "Ensino", ]$iGG
## W = 0.96869, p-value = 0.00777

As distribuições dentro dos grupos não são normais. Portanto, não podemos usar Anova. Vamos usar, então, um teste não paramétrico.

Teste de Kruskal-Wallis

Teste não paramétrico para verificar se as distribuições dos grupos testados são idênticas. A hipótese nula é que são identicas. Se p p-value do teste for maior que 0.05, então são identicas.

kruskal.test(iGG ~ Tipo, data = base_interesse)
## 
##  Kruskal-Wallis rank sum test
## 
## data:  iGG by Tipo
## Kruskal-Wallis chi-squared = 31.408, df = 4, p-value = 2.527e-06

Com o resultado acima, concluímos que, com um nível de significância de 0.05, os iGGs das populações não são identicos.

Ranqueamento do iGG por tipo

A partir do resultado acima, sabemos que há diferença significante entre os grupos, mas não sabemos quais pares são diferentes. É possível saber isso usando o teste Wilcoxon par-a-par com correções de níveis de agrupamentos para múltiplos testes. O R implementa esse teste com a função abaixo.

res_pw_wilcoxon = pairwise.wilcox.test(base_interesse$iGG, base_interesse$Tipo,
                                       p.adjust.method = "BH",
                                       alternative = "two.sided",
                                       exact = FALSE)

as.data.frame(res_pw_wilcoxon$p.value) %>%
  kable("html") %>%
  kable_styling(bootstrap_options = c("striped", "condensed", "hover"),
                                      full_width = FALSE, position = "left")
Autarquia Estatal Tribunal Ensino
Estatal 0.6980441 NA NA NA
Tribunal 0.6952734 0.3749074 NA NA
Ensino 0.0040213 0.0003404 0.0000104 NA
Saúde 0.1160399 0.0625083 0.0625083 0.2839222

A tabela acima mostra que (com um nível de significância de 0.05):

  • o iGG das Autarquias é equivalente aos de Estatais, Tribunais, Unidades de Saúde, mas distinto do de Instituições de Ensino
  • o IGG das Estatais é equivalente aos dos Tribunais e das Unidades de Saúde, mas distinto do de Instituições de Ensino
  • o IGG dos Tribunais é equivalente aos das Unidades de Saúde, mas distinto do de Instituições de Ensino
  • o IGG das Instituições de ensino é equivalente aos das Unidades de Saúde.

É importante notar que o IGG das Instituições de Ensino só é equivalente aos das Unidades de Saúde isoladamente. Já o IGG das Unidades de Saúde é equivalente a todos os demais IGG. Nota-se também que o p-value dos testes de equivalência do iGG das Unidades de Saúde e Estatais e Tribunais é bem perto do mínimo para aceitá-los como equivalentes. Assim, é possível ranquear o iGG dos tipos de instituição da seguinte maneira (do mais alto para o mais baixo)

  1. Autarquias, Tribunais e Estatais (empatados)
  2. Unidades de Saúde (por empatar com todos)
  3. Instituições de Ensino (por empatar apenas com Unidades de Saúde)
filtro_tipos = c("Autarquia", "Estatal", "Tribunal", "Saúde")
kruskal.test(iGG ~ Tipo, data = subset(base_interesse, Tipo %in% filtro_tipos))
## 
##  Kruskal-Wallis rank sum test
## 
## data:  iGG by Tipo
## Kruskal-Wallis chi-squared = 6.9938, df = 3, p-value = 0.0721

Possíveis Enganos Causados por Inspeção Visual

Para este trabalho, o teste par-a-par de Wilcoxon mostra que não há diferença estatística entre as medianas dos grupos Autarquias, Estatais, Tribunais e Unidades de Saúde. Entretanto, uma inspeção visual como a mostrada abaixo pode ensejar um erro de interpretação, principalmente no gráfico em que os intervalos de confiança não são plotados.

lin_media = ggline(base_interesse, x = "Tipo", y = "iGG", 
       add = c("mean"), 
       color = "steelblue",
       point.color = "red",
       ylab = "Média do iGG", xlab = "Tipo Entidade",
       ylim=c(0.33, 0.52))

lin_media_erro = ggline(base_interesse, x = "Tipo", y = "iGG", 
       add = c("mean_ci"), 
       color = "steelblue",
       point.color = "red",
       ylab = "Média do iGG com IC", xlab = "Tipo Entidade",
       ylim=c(0.33, 0.52))


ggarrange(lin_media, lin_media_erro,
          ncol = 2, nrow = 1)