Após minha última publicação apressada, percebi que precisava parar para dar uma estudada melhor na produção de tabelas no R. Assim, este texto pretente apresentar o pacote stargazer do R, que foi elaborado para disponibilizar a formulação de tabelas. Tanto de estatísticas descritivas, quanto de resultados de regressões.

Partindo para as aplicações, primeiro é necessário instalar e carregar o pacote.

#install.packages("stargazer")
library(stargazer)
## 
## Please cite as:
##  Hlavac, Marek (2018). stargazer: Well-Formatted Regression and Summary Statistics Tables.
##  R package version 5.2.2. https://CRAN.R-project.org/package=stargazer

A referência que está sendo utilizada é a mesma citada acima, Marek (2008).

A utilização é simples e basta inserir um data.frame na função stargazer(), para obter o mesmo resultado da função summary() da base de dados attitude. A base de dados attitude já vem com a instalação padrão do R.

stargazer(attitude, type = "html")
StatisticNMeanSt. Dev.MinPctl(25)Pctl(75)Max
rating3064.63312.1734058.871.885
complaints3066.60013.3153758.57790
privileges3053.13312.235304562.583
learning3056.36711.737344766.875
raises3064.63310.3974358.27188
critical3074.7679.8954969.28092
advance3042.93310.289253547.872

Também é possível apresentar apenas os dados, sem o sua análise descritiva.

stargazer(attitude[1:4,], summary=FALSE, rownames=FALSE, type = "html")
ratingcomplaintsprivilegeslearningraisescriticaladvance
43513039619245
63645154637347
71706869768648
61634547548435

Observe que estou inserindo a opção type = "html". Faço isso por que estou gerando as tabelas para um arquivo em html, uma página de internet. Caso não coloque nada, a função assume o type = "latex" que é o formato padrão. Esta opção padrão pode ser mantida se for produzido um texto em pdf, gerado no RMarkdown1. Uma terceira opção é gerar uma tabela no formato ASCI, colocando type = "text", que é uma tabela para arquivos “txt” (que não fica legal no word). Assim, se a ideia for gerar tabelas para colocar em documentos de word, o melhor caminho é gerar em pdf no Rmarkdown, copiar e colar no Word.

Resultados de Modelos

Seguindo o material de Marek (2008), são apresentados dois modelos de regressão linear, lm(), e um probit, glm().

Abaixo, os modelos são gerados em separado da tabela e utilizam a mesma base de dados, attitude.

##  Modelos Lineares
linear.1 <- lm(rating ~ complaints + privileges + learning + raises + critical,
               data=attitude)
linear.2 <- lm(rating ~ complaints + privileges + learning,
               data=attitude)
## Probit
#Indicador verdadeiro ou falso (0 ou 1) para variável dependente do modelo
attitude$high.rating <- (attitude$rating > 70)

# modelo probit
probit.model <- glm(high.rating ~ learning + critical + advance,
                    data=attitude,
                    family = binomial(link = "probit"))

Assim, são três os modelos a serem analisados. Note, abaixo, que a função é automatizada. Basta colocar os modelos que ela os insere em conjunto. Além dos modelos, é inserido o argumento title =, o título da tabela, e o argumento align = TRUE, que alinha os valores da tabela.

stargazer(linear.1, linear.2, probit.model,
          title="Resultados",
          align=T,
          type = "html")
Resultados
Dependent variable:
ratinghigh.rating
OLSprobit
(1)(2)(3)
complaints0.692***0.682***
(0.149)(0.129)
privileges-0.104-0.103
(0.135)(0.129)
learning0.2490.238*0.164***
(0.160)(0.139)(0.053)
raises-0.033
(0.202)
critical0.015-0.001
(0.147)(0.044)
advance-0.062
(0.042)
Constant11.01111.258-7.476**
(11.704)(7.318)(3.570)
Observations303030
R20.7150.715
Adjusted R20.6560.682
Log Likelihood-9.087
Akaike Inf. Crit.26.175
Residual Std. Error7.139 (df = 24)6.863 (df = 26)
F Statistic12.063*** (df = 5; 24)21.743*** (df = 3; 26)
Note:*p<0.1; **p<0.05; ***p<0.01

É possível fazer mais ajustes. Na composição seguinte, além das opções anteriores, foram inseridos nomes (labels) para as variáveis dependentes, com o argumento dep.var.labels. Note que são só dois nomes, pois são duas variáveis dependentes diferentes em três modelos distintos. Também é especificado o nome das “covariáveis”, ou variáveis explicativas, com o argumento covariate.labels.

Para contextualizar, a base de dados é o resultado de uma pesquisa com funcionários administrativos em uma grande organização financeira. Ela está agregada em 30 setores (amostra), uma descrição (muito breve) dessa base pode ser encontrada aqui. Digo isso, pois traduzi as variáveis para fazer mais sentido, mas não sei se não acabei piorando as coisas.

Avançando nas opções, foram omitidas as estatísticas LogLikelihood (LL), erro padrão (ser) e teste F (f), utilizando o argumento omit.stat. E foram retirados os espaços em branco da tabela com o argumento no.space.

stargazer(linear.1, linear.2, probit.model, 
          title="Resultados", 
          align=TRUE,
          type = "html",
          dep.var.labels=c("Taxa Nominal","Taxas Elevadas (>70%)"),
          covariate.labels=c("Tratamento das Reclamações",
                             "Não permite privilégios",
                             "Oportunidades de Aprendizado",
                             "Aumentos por performance",
                             "Crítica",
                             "Avanço", 
                             "Constante"),
          omit.stat=c("LL","ser","f"),
          no.space=TRUE)
Resultados
Dependent variable:
Taxa NominalTaxas Elevadas (>70%)
OLSprobit
(1)(2)(3)
Tratamento das Reclamações0.692***0.682***
(0.149)(0.129)
Não permite privilégios-0.104-0.103
(0.135)(0.129)
Oportunidades de Aprendizado0.2490.238*0.164***
(0.160)(0.139)(0.053)
Aumentos por performance-0.033
(0.202)
Crítica0.015-0.001
(0.147)(0.044)
Avanço-0.062
(0.042)
Constante11.01111.258-7.476**
(11.704)(7.318)(3.570)
Observations303030
R20.7150.715
Adjusted R20.6560.682
Akaike Inf. Crit.26.175
Note:*p<0.1; **p<0.05; ***p<0.01

Outra sugestão feita por Marek (2008) é a da tabela a seguir. Os intervalos dos coeficientes, a 90% de significância estatística, são inseridos com os argumentos ci e ci.level. Tudo colocado na mesma linha com single.row. Note que estão sendo usados apenas os dois modelos lineares e que, mesmo assim, apenas um label, “Taxa Nominal”, aparece.

stargazer(linear.1, linear.2,
          title="Resultados",
          align = F,
          type = "html",
          dep.var.labels=c("Taxa Nominal","Taxas Elevadas (>70%)"),
          covariate.labels=c("Tratamento das Reclamações",
                             "Não permite privilégios",
                             "Oportunidades de Aprendizado",
                             "Aumentos por performance",
                             "Crítica",
                             "Avanço", 
                             "Constante"),
          omit.stat=c("LL","ser","f"), 
          ci=TRUE, 
          ci.level=0.90, 
          single.row=TRUE)
Resultados
Dependent variable:
Taxa Nominal
(1)(2)
Tratamento das Reclamações0.692*** (0.447, 0.937)0.682*** (0.470, 0.894)
Não permite privilégios-0.104 (-0.325, 0.118)-0.103 (-0.316, 0.109)
Oportunidades de Aprendizado0.249 (-0.013, 0.512)0.238* (0.009, 0.467)
Aumentos por performance-0.033 (-0.366, 0.299)
Crítica0.015 (-0.227, 0.258)
Avanço11.011 (-8.240, 30.262)11.258 (-0.779, 23.296)
Observations3030
R20.7150.715
Adjusted R20.6560.682
Note:*p<0.1; **p<0.05; ***p<0.01

Uma versão ainda mais sintética da tabela é apresentada em seguida. Retirando todas as estatísticas com, keep.stat="n". Nela as variáveis learnings e privileges são destacadas (trazidas) no começo da tabela com o order.

stargazer(linear.1, linear.2, 
          title="Resultados",
          type = "html",
          dep.var.labels=c("Taxa Nominal","Taxas Elevadas (>70%)"),
          order=c("learning", "privileges"),
          keep.stat="n",
          ci=TRUE,
          ci.level=0.90,
          single.row=TRUE)
Resultados
Dependent variable:
Taxa Nominal
(1)(2)
learning0.249 (-0.013, 0.512)0.238* (0.009, 0.467)
privileges-0.104 (-0.325, 0.118)-0.103 (-0.316, 0.109)
complaints0.692*** (0.447, 0.937)0.682*** (0.470, 0.894)
raises-0.033 (-0.366, 0.299)
critical0.015 (-0.227, 0.258)
Constant11.011 (-8.240, 30.262)11.258 (-0.779, 23.296)
Observations3030
Note:*p<0.1; **p<0.05; ***p<0.01

Matrizes

O autor também destaca que é possível representar matrizes de correlação. No caso são utilizadas apenas três variáveis.

correlation.matrix <- 
  cor(attitude[,c("rating","complaints","privileges")])

stargazer(correlation.matrix,
          title="Matriz de Correlação",
          type = "html")
Matriz de Correlação
ratingcomplaintsprivileges
rating10.8250.426
complaints0.82510.558
privileges0.4260.5581

Considerações finais

Marek (2008) ainda apresenta como inserir “erros customizados”, para regressões robustas. Não vou me prender a essa replicação aqui, pois foi usada uma programação muito longa e com muitos detalhes para explicar. De qualquer forma, os erros padrão (se), podem ser alterados na tabela, inserindo-os com o argumento se =.

Espero que tenha sido útil, meu esforço aqui foi só o de reproduzir um material que já está disponível em inglês. Basicamente uma tradução sintética de algumas funcionalidades do pacote, pois eu mesmo precisava parar para fazer essa leitura.


  1. Importante, caso gere tabelas ou documentos no Rmarkdown e queira visualizar em html como fiz aqui, é necessário inserir a opção results='asis' nos chuncks dos códigos. [return]