Olá. Os bancos de dados que vamos usar nesta parte da aula estão disponíveis em http://bit.ly/2dnrHmZ.

Importando bancos de dados

Podemos importar um banco de dados no R usando os comandos read.table().

options(scipen=999)
dados <- read.table("enade_2014_amostra.csv", sep = ";", stringsAsFactors = F, header = T)

Há outros comandos para importar bancos de dados em estruturas específicas, como separados por vírgulas (.csv), separados por ponto-e-vírgula, separados por tab (.tsv), bancos de dados em formato fixo (como a PNAD). Você pode investigar cada um deles usando o comando help() ou sua versão compacta, ?.

help("read.csv")
?read.fwf
?read.csv2

Importando dados com o pacote readr

Um dos maiores desenvolvedores para linguagem R, Hadley Wickham, desenvolveu um pacote muito eficiente para leitura de bancos de dados chamado readr. Como sabemos que trata-se de um arquivo .csv separado por ponto-e-vírgula, devemos usar o comando read_csv2. Vamos experimentá-lo comparando seu desempenho com o comando da base do R:

system.time(dados <- read.csv2("enade_2014_amostra.csv", stringsAsFactors = F, header = T))
##    user  system elapsed 
##   0.548   0.000   0.544
library(readr)
system.time(dados <- read_csv2("enade_2014_amostra.csv", col_names = T))
##    user  system elapsed 
##   0.128   0.000   0.128

Veja como a função read_csv2() é mais de 3 vezes mais rápida do que a função base!!! O Wickham tem ainda vários outros pacotes desenvolvidos para manipulação de dados string, manipulação de bancos de dados, transformação de variáveis, dentre outros. Esses pacotes podem tornar a nossa vida bem mais fácil! Veja uma apresentação sobre o hadleyverse, universo de Hadley em http://barryrowlingson.github.io/hadleyverse.

Para importar dados de outros programas como SPSS, Stata ou SAS, você pode usar o pacote foreign.

library(foreign)
?read.spss # lê SPSS
?read.dta  # lê Stata
?read.ssd  # lê SAS
?read.xport # lê SAS

Bônus: Introdução ao ggplot2

ggplot2 é um pacote desenvolvido por (adivinha?) Hadley Wickham para a construção de gráficos de alta qualidade e alta customização. Gráficos desse pacote se tornaram um standard no meio acadêmico podendo ser encontrados nas principais revistas de análise quantitativa.

Sua sintaxe é a seguinte:

ggplot(data = "banco de dados", aes(x = "vetor x", y = "vetor y")) + tipo de gráfico (podem ser vários aninhados)

Vamos repetir alguns gráficos gerados com o banco de dados iris agora com o pacote ggplot2.

library(ggplot2)
data(iris)
# Gerando um histograma
ggplot(data=iris, aes(x=Petal.Length))+geom_histogram()

# Gerando um scatterplot
ggplot(data=iris, aes(x=Petal.Length, y=Sepal.Length))+geom_point()

# Gerando um boxplot e um violinplot
ggplot(data=iris, aes(x=Species, y=Petal.Length))+geom_boxplot()

ggplot(data=iris, aes(x=Species, y=Petal.Length))+geom_violin()

# Gerando um gráfico de barras
ggplot(data=iris, aes(x=Species))+geom_bar()

# Podemos inclusive plotar uma reta de regressão
ggplot(data=iris, aes(x=Petal.Length, y=Sepal.Length))+geom_point()+geom_smooth(method="lm")

Algumas análises com dados da PNAD

Vamos realizar algumas análises com os dados da PNAD 2012. Primeiro importamos o banco de dados.

library(foreign)
pnad <- read.spss("pes_2012.sav", to.data.frame = T)
head(pnad)
##   V0101       UF     V0302 V8005  V0404           V4803 V4718 V4720 V4729
## 1  2012 Rondônia Masculino    48 Branca 15 anos ou mais  3000  3000   232
## 2  2012 Rondônia  Feminino    48 Branca 15 anos ou mais  3000  3000   232
## 3  2012 Rondônia  Feminino    23 Branca 15 anos ou mais  1100  1100   232
## 4  2012 Rondônia  Feminino    21 Branca         14 anos  1100  1100   232
## 5  2012 Rondônia  Feminino    54 Branca 15 anos ou mais    NA   460   232
## 6  2012 Rondônia Masculino    56  Preta 15 anos ou mais 10000 10000   232

Vamos ver a variável sexo (V0302):

library(descr)
freq(pnad$V0302)

## pnad$V0302 
##           Frequência Percentual
## Masculino     176397      48.67
## Feminino      186054      51.33
## Total         362451     100.00

Vamos verificar a idade (V8005) média, e depois a idade média de homens e mulheres. Podemos verificar a idade por grupos de sexo fazendo subsetting ou realizando um teste de médias.

mean(pnad$V8005)
## [1] 32.63801
# Média ponderada pelo peso amostral
weighted.mean(pnad$V8005, pnad$V4729)
## [1] 33.0607
# Média por grupos de sexo
mean(pnad$V8005[pnad$V0302 == "Masculino"])
## [1] 31.62186
mean(pnad$V8005[pnad$V0302 == "Feminino"])
## [1] 33.60142
t.test(pnad$V8005~pnad$V0302)
## 
##  Welch Two Sample t-test
## 
## data:  pnad$V8005 by pnad$V0302
## t = -28.734, df = 362230, p-value < 0.00000000000000022
## alternative hypothesis: true difference in means is not equal to 0
## 95 percent confidence interval:
##  -2.114581 -1.844524
## sample estimates:
## mean in group Masculino  mean in group Feminino 
##                31.62186                33.60142

Vamos verificar agora a variável cor (V0404). Vamos elaborar uma tabela de contingência cor X sexo.

freq(pnad$V0404)

## pnad$V0404 
##                Frequência Percentual
## Indígena             1435   0.395916
## Branca             155595  42.928561
## Preta               30120   8.310089
## Amarela              1550   0.427644
## Parda              173733  47.932824
## Sem declaração         18   0.004966
## Total              362451 100.000000
table(pnad$V0404,pnad$V0302)
##                 
##                  Masculino Feminino
##   Indígena             721      714
##   Branca             73465    82130
##   Preta              15222    14898
##   Amarela              682      868
##   Parda              86298    87435
##   Sem declaração         9        9

Agora vamos investigar a variável renda mensal do trabalho principal. Para isso, é preciso codificar o valor 999999999999 como NA.

summary(pnad$V4718)
##          Min.       1st Qu.        Median          Mean       3rd Qu. 
##             0           622           800   26260000000          1500 
##          Max.          NA's 
## 1000000000000        188912
# Veja que, após a recodificação dos NA's, as medidas estatísticas mudam
pnad$V4718[pnad$V4718 >= 999999999999] = NA
summary(pnad$V4718)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max.    NA's 
##       0     622     800    1343    1400  350000  193470
hist(pnad$V4718)

Vamos testar algumas diferenças de salários por sexo e cor. Para testar por cor, vamos criar uma variável dummy branco. Para isso, usaremos o comando ifelse(). Ele funciona da seguinte maneira: se a condição determinada for cumprida, atribui-se o primeiro valor. Se não, atribui-se o segundo valor.

# Testando por sexo
t.test(pnad$V4718~pnad$V0302)
## 
##  Welch Two Sample t-test
## 
## data:  pnad$V4718 by pnad$V0302
## t = 36.656, df = 163240, p-value < 0.00000000000000022
## alternative hypothesis: true difference in means is not equal to 0
## 95 percent confidence interval:
##  421.982 469.657
## sample estimates:
## mean in group Masculino  mean in group Feminino 
##                1532.572                1086.752
# Criando a dummy branco
# Se pnad$V0404 for igual a "branca", atribua 1. Se não, atribua 0.
pnad$branco <- ifelse(pnad$V0404 == "Branca", 1, 0)
pnad$branco <- as.factor(pnad$branco) # transforma em factor
levels(pnad$branco) <- c("Não Branco","Branco") # coloca os labels
freq(pnad$branco, plot=F)  # verifica a distribuição
## pnad$branco 
##            Frequência Percentual
## Não Branco     206856      57.07
## Branco         155595      42.93
## Total          362451     100.00
# Será que brancos ganham mais, menos, ou igual a não brancos no Brasil?
t.test(pnad$V4718~pnad$branco)
## 
##  Welch Two Sample t-test
## 
## data:  pnad$V4718 by pnad$branco
## t = -51.066, df = 92293, p-value < 0.00000000000000022
## alternative hypothesis: true difference in means is not equal to 0
## 95 percent confidence interval:
##  -750.1254 -694.6719
## sample estimates:
## mean in group Não Branco     mean in group Branco 
##                 1027.188                 1749.587

Vamos testar agora algumas correlações entre renda, escolaridade e idade. Para isso, é necessário retirar os NA’s.

pnad_semna <- na.omit(pnad) # tira NA's e guarda no objeto pnad_semna

# Renda, escolaridade e idade
cor(cbind(pnad_semna$V4718, as.numeric(pnad_semna$V4803), pnad_semna$V8005))
##           [,1]       [,2]       [,3]
## [1,] 1.0000000  0.2605251  0.1046775
## [2,] 0.2605251  1.0000000 -0.2547903
## [3,] 0.1046775 -0.2547903  1.0000000

Regressão linear - Exemplo com ENADE 2014

Vamos montar um modelinho de regressão para tentar explicar o desempenho dos alunos no ENADE como função do sexo, da idade e da cor. Para isso, primeiro devemos verificar a distribuição da variável resposta.

enade <- read_csv2("enade_2014_amostra.csv", col_names = T)
hist(enade$nt_ger, col = "blue")

A variável possui distribuição normal e portanto é uma boa variável para aplicar regressão linear por MQO. Agora, após, ver algumas estatísticas descritivas, vamos montar o modelo:

summary(enade$nt_ger)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max.    NA's 
##     0.0   292.0   414.0   399.6   528.0   943.0    1724
# Colocando NA's nas não respostas da variável sexo
enade$tp_sexo[enade$tp_sexo == "N"] = NA
freq(enade$tp_sexo, plot=F)
## enade$tp_sexo 
##       Frequência Percentual % Válido
## F           5744      57.44    57.45
## M           4254      42.54    42.55
## NA's           2       0.02         
## Total      10000     100.00   100.00
# Idade
summary(enade$nu_idade)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   18.00   23.00   27.00   29.89   34.00   73.00
# Cor
class(enade$qe_i2)
## [1] "character"
enade$qe_i2 <- as.factor(enade$qe_i2) # transformando em factor

# colocando os labels
levels(enade$qe_i2) <- c("Branco","Negro","Pardo","Amarelo","Indígena")
freq(enade$qe_i2, plot=F)
## enade$qe_i2 
##          Frequência Percentual % Válido
## Branco         4606      46.06  52.9791
## Negro           893       8.93  10.2715
## Pardo          2988      29.88  34.3685
## Amarelo         129       1.29   1.4838
## Indígena         78       0.78   0.8972
## NA's           1306      13.06         
## Total         10000     100.00 100.0000

A sintaxe do modelo de regressão funciona da seguinte forma:

lm(dependente ~ preditor1 + preditor2 + preditor3, data = banco de dados)

# Montando o modelo
modelo <- lm(nt_ger ~ tp_sexo + nu_idade + qe_i2, data=enade)
summary(modelo) # apresenta os resultados do modelo
## 
## Call:
## lm(formula = nt_ger ~ tp_sexo + nu_idade + qe_i2, data = enade)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -425.92 -106.49   13.69  127.53  521.92 
## 
## Coefficients:
##               Estimate Std. Error t value             Pr(>|t|)    
## (Intercept)   448.8788     7.8895  56.896 < 0.0000000000000002 ***
## tp_sexoM        0.6301     4.1269   0.153             0.878656    
## nu_idade       -1.2085     0.2409  -5.017       0.000000535724 ***
## qe_i2Negro    -25.9165     6.9206  -3.745             0.000182 ***
## qe_i2Pardo    -28.6309     4.4442  -6.442       0.000000000124 ***
## qe_i2Amarelo  -19.1198    16.4444  -1.163             0.244987    
## qe_i2Indígena -50.1873    21.4993  -2.334             0.019600 *  
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 183.4 on 8235 degrees of freedom
##   (1758 observations deleted due to missingness)
## Multiple R-squared:  0.009782,   Adjusted R-squared:  0.009061 
## F-statistic: 13.56 on 6 and 8235 DF,  p-value: 0.000000000000002249

Podemos interpretar este modelo da seguinte forma:

Homens não tem diferença estatisticamente significante das mulheres em relação à nota geral. Para cada 1 ano a mais de idade, a nota geral diminui, em média, 1.21 pontos. No caso da variável Cor, por se tratar de uma variável categórica, todos os coeficientes serão interpretados em relação à categoria de referência, a que foi retirada. Neste caso, negros tem, em média, uma nota 25.9 pontos menor que brancos; pardos tem, em média, uma nota 28.6 pontos menor que brancos, e indígenas tem, em média, uma nota -50 pontos menor que brancos mantendo-se todas as demais variáveis constantes. O coeficiente para a categoria amarelo não foi estatisticamente significativo, ou seja, a diferença entre as notas desse grupo e dos brancos é estatisticamente igual a 0.

Agora vamos avaliar nosso modelo. O R nos dá alguns gráficos default de avaliação.

# gráficos de avaliação
plot(modelo)

Para realizar uma análise dos resíduos da regressão, podemos tirar um histograma. O comando residuals() extrai os resíduos de um modelo estatístico.

# Histograma dos resíduos
hist(residuals(modelo), col = "red")

Depois disso, podemos plotar a reta de regressão usando o comando plot() e o comando abline(). O comando abline() toma como argumentos o intercepto e a inclinação (coeficiente) da variável que desejamos plotar.

# Plotando a reta de regressão
coef(modelo) # verificando apenas os coeficientes do modelo
##   (Intercept)      tp_sexoM      nu_idade    qe_i2Negro    qe_i2Pardo 
##   448.8788071     0.6300838    -1.2084605   -25.9164527   -28.6308728 
##  qe_i2Amarelo qe_i2Indígena 
##   -19.1197937   -50.1872827
plot(enade$nu_idade, enade$nt_ger, pch=19) # plotando as variáveis
abline(a=448.8764, b=-1.2085, col="red", lwd = 2) #plotando uma reta com intercepto e slope

# BONUS: o mesmo gráfico com ggplot2
library(ggplot2)
ggplot(enade, aes(nu_idade, nt_ger))+geom_point()+
  geom_abline(intercept = 448.8764, slope = -1.2085, col="red", lwd=1)+
  labs(title="Reta de regressão", x="Idade", y="Nota Geral")