Referências para leitura deste material:
Nas primeiras quatro seções deste material discutiremos exemplos que
utilizam o seguinte conjunto de dados, extraído do Capítulo 2 da
referência Morettin & Bussab (2010). A função
read.table() pode ser usada para ler um arquivo externo do
tipo .txt. A função read.csv() faz o mesmo para arquivos do
tipo .csv (comma-separated values file).
df0 <- read.table(file="tab.txt",header=TRUE,stringsAsFactors=FALSE)
df0
## N estado_civil grau_instrucao n_filhos salario idade reg_procedencia
## 1 1 solteiro fundamental NA 4.00 26 interior
## 2 2 casado fundamental 1 4.56 32 capital
## 3 3 casado fundamental 2 5.25 36 capital
## 4 4 solteiro medio NA 5.73 20 outra
## 5 5 solteiro fundamental NA 6.26 40 outra
## 6 6 casado fundamental 0 6.66 28 interior
## 7 7 solteiro fundamental NA 6.86 41 interior
## 8 8 solteiro fundamental NA 7.39 43 capital
## 9 9 casado medio 1 7.59 34 capital
## 10 10 solteiro medio NA 7.44 23 outra
## 11 11 casado medio 2 8.12 33 interior
## 12 12 solteiro fundamental NA 8.46 27 capital
## 13 13 solteiro medio NA 8.74 37 outra
## 14 14 casado fundamental 3 8.95 44 outra
## 15 15 casado medio 0 9.13 30 interior
## 16 16 solteiro medio NA 9.35 38 outra
## 17 17 casado medio 1 9.77 31 capital
## 18 18 casado fundamental 2 9.80 39 outra
## 19 19 solteiro superior NA 10.53 25 interior
## 20 20 solteiro medio NA 10.76 37 interior
## 21 21 casado medio 1 11.06 30 outra
## 22 22 solteiro medio NA 11.59 34 capital
## 23 23 solteiro fundamental NA 12.00 41 outra
## 24 24 casado superior 0 12.79 26 outra
## 25 25 casado medio 2 13.23 32 interior
## 26 26 casado medio 2 13.60 35 outra
## 27 27 solteiro fundamental NA 13.85 46 outra
## 28 28 casado medio 0 14.69 29 interior
## 29 29 casado medio 5 14.71 40 interior
## 30 30 casado medio 2 15.99 35 capital
## 31 31 solteiro superior NA 16.22 31 outra
## 32 32 casado medio 1 16.61 36 interior
## 33 33 casado superior 3 17.26 43 capital
## 34 34 solteiro superior NA 18.75 33 capital
## 35 35 casado medio 2 19.40 48 capital
## 36 36 casado superior 3 23.30 42 interior
Uma vez que o conjunto de dados foi lido e armazenada em um objeto, é
necessário conhecer sua estrutura. Isto significa, saber quantas
observações existem, quantas e quais são as variáveis envolvidas, seus
tipos e valores. Esta tarefa pode ser feita com a função
str(). A função head() mostra as 6 primeiras
linhas de um conjunto de dados e a função tail() mostra as
6 últimas linhas. A função class() retorna a estrutura de
dados que foi utilizada para armazenar as variáveis do conjunto de dados
em questão. No caso a estrutura utilizada foi um data frame.
str(df0)
## 'data.frame': 36 obs. of 7 variables:
## $ N : int 1 2 3 4 5 6 7 8 9 10 ...
## $ estado_civil : chr "solteiro" "casado" "casado" "solteiro" ...
## $ grau_instrucao : chr "fundamental" "fundamental" "fundamental" "medio" ...
## $ n_filhos : int NA 1 2 NA NA 0 NA NA 1 NA ...
## $ salario : num 4 4.56 5.25 5.73 6.26 6.66 6.86 7.39 7.59 7.44 ...
## $ idade : int 26 32 36 20 40 28 41 43 34 23 ...
## $ reg_procedencia: chr "interior" "capital" "capital" "outra" ...
head(df0)
## N estado_civil grau_instrucao n_filhos salario idade reg_procedencia
## 1 1 solteiro fundamental NA 4.00 26 interior
## 2 2 casado fundamental 1 4.56 32 capital
## 3 3 casado fundamental 2 5.25 36 capital
## 4 4 solteiro medio NA 5.73 20 outra
## 5 5 solteiro fundamental NA 6.26 40 outra
## 6 6 casado fundamental 0 6.66 28 interior
tail(df0)
## N estado_civil grau_instrucao n_filhos salario idade reg_procedencia
## 31 31 solteiro superior NA 16.22 31 outra
## 32 32 casado medio 1 16.61 36 interior
## 33 33 casado superior 3 17.26 43 capital
## 34 34 solteiro superior NA 18.75 33 capital
## 35 35 casado medio 2 19.40 48 capital
## 36 36 casado superior 3 23.30 42 interior
class(df0)
## [1] "data.frame"
A função summary() proporciona uma síntese numérica rápida
e simplificada para todas as variáveis de um conjunto de dados.
summary(df0)
## N estado_civil grau_instrucao n_filhos
## Min. : 1.00 Length:36 Length:36 Min. :0.00
## 1st Qu.: 9.75 Class :character Class :character 1st Qu.:1.00
## Median :18.50 Mode :character Mode :character Median :2.00
## Mean :18.50 Mean :1.65
## 3rd Qu.:27.25 3rd Qu.:2.00
## Max. :36.00 Max. :5.00
## NA's :16
## salario idade reg_procedencia
## Min. : 4.000 Min. :20.00 Length:36
## 1st Qu.: 7.553 1st Qu.:30.00 Class :character
## Median :10.165 Median :34.50 Mode :character
## Mean :11.122 Mean :34.58
## 3rd Qu.:14.060 3rd Qu.:40.00
## Max. :23.300 Max. :48.00
##
Note que a função summary não proporcionou uma síntese
adequada para as variáveis categóricas: estado civil,
grau de instrução e região de
procedência. Isso ocorreu porque estas variáveis estão
armazenadas em df0 como vetores de caracteres (veja a
estrutura de df0 para confirmar esta observação). Ainda que
em situações simples seja possível realizar análises de variáveis
categóricas armazenadas como vetores de caracteres, é mais adequado
utilizar a estrutura factor() (fator em Português) para
armazenar tais variáveis. O script que segue realiza esta conversão de
vetores de caracteres para fatores para as variáveis em questão.
#
# Vamos preservar df0 apenas para comparação
#
df <- df0
niveis.ec <- c("solteiro","casado")
niveis.gi <- c("fundamental","medio","superior")
niveis.rp <- c("capital","interior","outra")
df$estado_civil <- factor(df$estado_civil,levels=niveis.ec)
df$grau_instrucao <- factor(df$grau_instrucao,levels=niveis.gi,ordered=TRUE)
df$reg_procedencia <- factor(df$reg_procedencia,levels=niveis.rp)
#
# Variáveis como fatores em df
#
df$estado_civil
## [1] solteiro casado casado solteiro solteiro casado solteiro solteiro
## [9] casado solteiro casado solteiro solteiro casado casado solteiro
## [17] casado casado solteiro solteiro casado solteiro solteiro casado
## [25] casado casado solteiro casado casado casado solteiro casado
## [33] casado solteiro casado casado
## Levels: solteiro casado
df$grau_instrucao
## [1] fundamental fundamental fundamental medio fundamental fundamental
## [7] fundamental fundamental medio medio medio fundamental
## [13] medio fundamental medio medio medio fundamental
## [19] superior medio medio medio fundamental superior
## [25] medio medio fundamental medio medio medio
## [31] superior medio superior superior medio superior
## Levels: fundamental < medio < superior
df$reg_procedencia
## [1] interior capital capital outra outra interior interior capital
## [9] capital outra interior capital outra outra interior outra
## [17] capital outra interior interior outra capital outra outra
## [25] interior outra outra interior interior capital outra interior
## [33] capital capital capital interior
## Levels: capital interior outra
Compare agora com as estruturas de df e df0.
str(df)
## 'data.frame': 36 obs. of 7 variables:
## $ N : int 1 2 3 4 5 6 7 8 9 10 ...
## $ estado_civil : Factor w/ 2 levels "solteiro","casado": 1 2 2 1 1 2 1 1 2 1 ...
## $ grau_instrucao : Ord.factor w/ 3 levels "fundamental"<..: 1 1 1 2 1 1 1 1 2 2 ...
## $ n_filhos : int NA 1 2 NA NA 0 NA NA 1 NA ...
## $ salario : num 4 4.56 5.25 5.73 6.26 6.66 6.86 7.39 7.59 7.44 ...
## $ idade : int 26 32 36 20 40 28 41 43 34 23 ...
## $ reg_procedencia: Factor w/ 3 levels "capital","interior",..: 2 1 1 3 3 2 2 1 1 3 ...
str(df0)
## 'data.frame': 36 obs. of 7 variables:
## $ N : int 1 2 3 4 5 6 7 8 9 10 ...
## $ estado_civil : chr "solteiro" "casado" "casado" "solteiro" ...
## $ grau_instrucao : chr "fundamental" "fundamental" "fundamental" "medio" ...
## $ n_filhos : int NA 1 2 NA NA 0 NA NA 1 NA ...
## $ salario : num 4 4.56 5.25 5.73 6.26 6.66 6.86 7.39 7.59 7.44 ...
## $ idade : int 26 32 36 20 40 28 41 43 34 23 ...
## $ reg_procedencia: chr "interior" "capital" "capital" "outra" ...
Compare agora com o summary(df) com o
summary(df0).
summary(df)
## N estado_civil grau_instrucao n_filhos
## Min. : 1.00 solteiro:16 fundamental:12 Min. :0.00
## 1st Qu.: 9.75 casado :20 medio :18 1st Qu.:1.00
## Median :18.50 superior : 6 Median :2.00
## Mean :18.50 Mean :1.65
## 3rd Qu.:27.25 3rd Qu.:2.00
## Max. :36.00 Max. :5.00
## NA's :16
## salario idade reg_procedencia
## Min. : 4.000 Min. :20.00 capital :11
## 1st Qu.: 7.553 1st Qu.:30.00 interior:12
## Median :10.165 Median :34.50 outra :13
## Mean :11.122 Mean :34.58
## 3rd Qu.:14.060 3rd Qu.:40.00
## Max. :23.300 Max. :48.00
##
summary(df0)
## N estado_civil grau_instrucao n_filhos
## Min. : 1.00 Length:36 Length:36 Min. :0.00
## 1st Qu.: 9.75 Class :character Class :character 1st Qu.:1.00
## Median :18.50 Mode :character Mode :character Median :2.00
## Mean :18.50 Mean :1.65
## 3rd Qu.:27.25 3rd Qu.:2.00
## Max. :36.00 Max. :5.00
## NA's :16
## salario idade reg_procedencia
## Min. : 4.000 Min. :20.00 Length:36
## 1st Qu.: 7.553 1st Qu.:30.00 Class :character
## Median :10.165 Median :34.50 Mode :character
## Mean :11.122 Mean :34.58
## 3rd Qu.:14.060 3rd Qu.:40.00
## Max. :23.300 Max. :48.00
##
Uma síntese detalhada pode ser obtida com as seguintes funções. Como exemplo de síntese numérica de uma variável quantitativa contínua, considere a variável salário.
df$salario
## [1] 4.00 4.56 5.25 5.73 6.26 6.66 6.86 7.39 7.59 7.44 8.12 8.46
## [13] 8.74 8.95 9.13 9.35 9.77 9.80 10.53 10.76 11.06 11.59 12.00 12.79
## [25] 13.23 13.60 13.85 14.69 14.71 15.99 16.22 16.61 17.26 18.75 19.40 23.30
summary(df$salario)
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 4.000 7.553 10.165 11.122 14.060 23.300
mean(df$salario)
## [1] 11.12222
median(df$salario)
## [1] 10.165
quantile(df$salario,c(0.25,0.50,0.75))
## 25% 50% 75%
## 7.5525 10.1650 14.0600
IQR(df$salario) # Retorna a distância interquartil = Q3 - Q1.
## [1] 6.5075
min(df$salario)
## [1] 4
max(df$salario)
## [1] 23.3
var(df$salario)
## [1] 21.04477
sd(df$salario)
## [1] 4.587458
Como exemplo de síntese numérica de uma variável quantitativa discreta, considere a variável número de filhos.
df$n_filhos
## [1] NA 1 2 NA NA 0 NA NA 1 NA 2 NA NA 3 0 NA 1 2 NA NA 1 NA NA 0 2
## [26] 2 NA 0 5 2 NA 1 3 NA 2 3
summary(df$n_filhos)
## Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
## 0.00 1.00 2.00 1.65 2.00 5.00 16
mean(df$n_filhos)
## [1] NA
#
# Note que a função mean() não retornou a média da variável número de filhos.
# Isto aconteceu porque na variável em questão existem valores não disponíveis
# (valores NA - Not Available values). Neste caso, é necessário informar ao R
# que estes valores não disponíveis devem ser removidos e que o cálculo deve ser
# realizado com as observações restantes. Isto é feito definindo o argumento
# na.rm como TRUE. Observação análoga vale para outras estatísticas.
#
mean(df$n_filhos,na.rm=TRUE)
## [1] 1.65
median(df$n_filhos,na.rm=TRUE)
## [1] 2
quantile(df$n_filhos,c(0.25,0.50,0.75),na.rm=TRUE)
## 25% 50% 75%
## 1 2 2
IQR(df$n_filhos,na.rm=TRUE)
## [1] 1
min(df$n_filhos,na.rm=TRUE)
## [1] 0
max(df$n_filhos,na.rm=TRUE)
## [1] 5
var(df$n_filhos,na.rm=TRUE)
## [1] 1.607895
sd(df$n_filhos,na.rm=TRUE)
## [1] 1.268028
table(df$n_filhos,useNA="no")
##
## 0 1 2 3 5
## 4 5 7 3 1
round(prop.table(table(df$n_filhos,useNA="no"))*100,2)
##
## 0 1 2 3 5
## 20 25 35 15 5
Uma tabela de frequências para a variável número de filhos pode ser construída com o seguinte script.
num.filhos <- c(names(table(df$n_filhos)),"Total")
frequencias <- c(table(df$n_filhos),sum(table(df$n_filhos)))
proporcoes <- round((frequencias/sum(table(df$n_filhos)))*100,2)
df.num.filhos <- data.frame(num.filhos,frequencias,proporcoes)
rownames(df.num.filhos) <- 1:length(num.filhos)
colnames(df.num.filhos) <- c("Número de filhos","Frequência","Frequência (%)")
df.num.filhos
## Número de filhos Frequência Frequência (%)
## 1 0 4 20
## 2 1 5 25
## 3 2 7 35
## 4 3 3 15
## 5 5 1 5
## 6 Total 20 100
| Número de filhos | Frequência | Frequência (%) |
|---|---|---|
| 0 | 4 | 20 |
| 1 | 5 | 25 |
| 2 | 7 | 35 |
| 3 | 3 | 15 |
| 5 | 1 | 5 |
| Total | 20 | 100 |
Como exemplo de síntese de uma variável categórica, considere a variável grau de instrução.
df$grau_instrucao
## [1] fundamental fundamental fundamental medio fundamental fundamental
## [7] fundamental fundamental medio medio medio fundamental
## [13] medio fundamental medio medio medio fundamental
## [19] superior medio medio medio fundamental superior
## [25] medio medio fundamental medio medio medio
## [31] superior medio superior superior medio superior
## Levels: fundamental < medio < superior
table(df$grau_instrucao)
##
## fundamental medio superior
## 12 18 6
round((table(df$grau_instrucao)/sum(table(df$grau_instrucao)))*100,2)
##
## fundamental medio superior
## 33.33 50.00 16.67
round(prop.table(table(df$grau_instrucao))*100,2)
##
## fundamental medio superior
## 33.33 50.00 16.67
Note que a função table() retorna as frequências nominais
dos valores observados da variável grau de instrução.
Sendo assim, uma tabela de frequências para esta variável pode ser
construída com o seguinte script.
grau <- c(names(table(df$grau_instrucao)),"Total")
frequencias <- c(table(df$grau_instrucao),sum(table(df$grau_instrucao)))
proporcoes <- round((frequencias/sum(table(df$grau_instrucao)))*100,2)
df.instrucao <- data.frame(grau,frequencias,proporcoes)
rownames(df.instrucao) <- 1:length(grau)
colnames(df.instrucao) <- c("Grau de instrução","Frequência","Frequência (%)")
df.instrucao
## Grau de instrução Frequência Frequência (%)
## 1 fundamental 12 33.33
## 2 medio 18 50.00
## 3 superior 6 16.67
## 4 Total 36 100.00
| Grau de instrução | Frequência | Frequência (%) |
|---|---|---|
| fundamental | 12 | 33.33 |
| medio | 18 | 50.00 |
| superior | 6 | 16.67 |
| Total | 36 | 100.00 |
Considere novamente a variável salário. Uma tabela de frequências para a variável salário pode ser construída com o seguinte script.
salario.d <- cut(df$salario,breaks=seq(4,24,4),right=FALSE)
classes <- levels(salario.d)
freq <- as.vector(table(salario.d))
freq.r <- round(100*as.vector(prop.table(freq)),2)
freq.a <- cumsum(freq.r)
df.salario <- data.frame(c(classes,"Total"),c(freq,sum(freq)),c(freq.r,sum(freq.r)),c(freq.a,NaN))
colnames(df.salario) <- c("Faixa salarial","Frequência","Frequência (%)","Frequência acumulada")
df.salario
## Faixa salarial Frequência Frequência (%) Frequência acumulada
## 1 [4,8) 10 27.78 27.78
## 2 [8,12) 12 33.33 61.11
## 3 [12,16) 8 22.22 83.33
## 4 [16,20) 5 13.89 97.22
## 5 [20,24) 1 2.78 100.00
## 6 Total 36 100.00 NaN
| Faixa salarial | Frequência | Frequência (%) | Frequência acumulada |
|---|---|---|---|
| [4,8) | 10 | 27.78 | 27.78 |
| [8,12) | 12 | 33.33 | 61.11 |
| [12,16) | 8 | 22.22 | 83.33 |
| [16,20) | 5 | 13.89 | 97.22 |
| [20,24) | 1 | 2.78 | 100.00 |
| Total | 36 | 100.00 | NaN |
A função hist() pode ser usada para construir o histograma
para a variável salário.
hist(df$salario,breaks=seq(4,24,4),freq=TRUE,right=FALSE,
xlim=c(0,25),ylim=c(0,14),col="lightblue",
xlab="Salario",ylab="Frequência",main="")
dev.off()
## null device
## 1
Alternativamente, é possível também construir o histograma densidade para a variável salário. No histograma densidade, a altura de cada barra é definida de tal forma que a área da barra é igual à frequência percentual da classe que ela representa. Assim, a soma das áreas de todas as barras do histograma é igual a 1. Em outras palavras, a área total do histograma é padronizada para 1 (ou 100%).
hist(df$salario,breaks=seq(4,24,4),freq=FALSE,right=FALSE,
xlim=c(0,25),ylim=c(0,0.10),col="lightsalmon",
xlab="Salario",ylab="Densidade",main="")
dev.off()
## null device
## 1
Considere novamente a variável número de filhos, resumida na seguinte tabela de frequências.
| Número de filhos | Frequência | Frequência (%) |
|---|---|---|
| 0 | 4 | 20 |
| 1 | 5 | 25 |
| 2 | 7 | 35 |
| 3 | 3 | 15 |
| 5 | 1 | 5 |
| Total | 20 | 100 |
A função barplot() pode ser usada para construir o gráfico
de barras para a variável número de filhos.
barplot(table(df$n_filhos),col="lightgoldenrod",main="",xlab="Número de filhos",ylab="Frequência")
dev.off()
## null device
## 1
Considere novamente a variável grau de instrução, resumida na seguinte tabela de frequências.
| Grau de instrução | Frequência | Frequência (%) |
|---|---|---|
| fundamental | 12 | 33.33 |
| medio | 18 | 50.00 |
| superior | 6 | 16.67 |
| Total | 36 | 100.00 |
A função pie() pode ser usada para construir o gráfico de
setores para a variável grau de instrução.
rotulos <- c("Fundamental","Médio","Superior")
cores <- c("lightblue","lightsalmon","lightgreen")
pie(table(df$grau_instrucao),labels=rotulos,col=cores)
dev.off()
## null device
## 1
Por fim, considere uma vez mais a variável salário. A
função boxplot() pode ser usada para construir o gráfico
box-plot para a variável salário.
summary(df$salario)
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 4.000 7.553 10.165 11.122 14.060 23.300
limite.superior <- min(max(df$salario),quantile(df$salario,0.75)+1.5*IQR(df$salario))
limite.inferior <- max(min(df$salario),quantile(df$salario,0.25)-1.5*IQR(df$salario))
c(limite.inferior,limite.superior)
## [1] 4.0 23.3
boxplot(df$salario,ylab="Salário",col="lightblue")
dev.off()
## null device
## 1
Nesta seção iremos considerar o seguinte conjunto de dados bivariado, extraído do Capítulo 4 da referência Morettin & Bussab (2010). Estamos interessados em verificar se a criação de determinado tipo de cooperativa está associado com o fator regional.
niveis.e <- c("SP","PR","RS")
niveis.c <- c("consumidor","produtor","escola","outras")
cooperativa.sp <- rep(niveis.c,c(214,237,78,119))
cooperativa.pr <- rep(niveis.c,c(51,102,126,22))
cooperativa.rs <- rep(niveis.c,c(111,304,139,48))
estado <- factor(rep(niveis.e,c(648,301,602)),levels=niveis.e)
cooperativa <- factor(c(cooperativa.sp,cooperativa.pr,cooperativa.rs),levels=niveis.c)
df1 <- data.frame(Estado=estado,Tipo.cooperativa=cooperativa)
str(df1)
## 'data.frame': 1551 obs. of 2 variables:
## $ Estado : Factor w/ 3 levels "SP","PR","RS": 1 1 1 1 1 1 1 1 1 1 ...
## $ Tipo.cooperativa: Factor w/ 4 levels "consumidor","produtor",..: 1 1 1 1 1 1 1 1 1 1 ...
head(df1)
## Estado Tipo.cooperativa
## 1 SP consumidor
## 2 SP consumidor
## 3 SP consumidor
## 4 SP consumidor
## 5 SP consumidor
## 6 SP consumidor
tail(df1)
## Estado Tipo.cooperativa
## 1546 RS outras
## 1547 RS outras
## 1548 RS outras
## 1549 RS outras
## 1550 RS outras
## 1551 RS outras
dim(df1)
## [1] 1551 2
Considerando o conjunto de dados desta seção. Uma tabela de frequências
de dupla entrada (ou tabela de contingência) para as variáveis
estado e tipo de cooperativa pode ser
construída aplicando as seguintes funções: table()e
addmargins().
tf <- table(df1[,1],df1[,2])
tf
##
## consumidor produtor escola outras
## SP 214 237 78 119
## PR 51 102 126 22
## RS 111 304 139 48
rownames(tf)
## [1] "SP" "PR" "RS"
colnames(tf)
## [1] "consumidor" "produtor" "escola" "outras"
margin.table(tf,1)
##
## SP PR RS
## 648 301 602
margin.table(tf,2)
##
## consumidor produtor escola outras
## 376 643 343 189
tf1 <- addmargins(tf)
tf1
##
## consumidor produtor escola outras Sum
## SP 214 237 78 119 648
## PR 51 102 126 22 301
## RS 111 304 139 48 602
## Sum 376 643 343 189 1551
is.matrix(tf) # confirma que a estrutura de dados de tf é uma matriz
## [1] TRUE
is.matrix(tf1) # confirma que a estrutura de dados de tf1 é uma matriz
## [1] TRUE
Alternativamente, podemos obter o mesmo resultado aplicando as seguintes
funções: apply(), rbind() e
cbind().
apply(tf,1,sum)
## SP PR RS
## 648 301 602
apply(tf,2,sum)
## consumidor produtor escola outras
## 376 643 343 189
tf2 <- rbind(cbind(tf,apply(tf,1,sum)),apply(cbind(tf,apply(tf,1,sum)),2,sum))
rownames(tf2) <- c(rownames(tf),"total")
colnames(tf2) <- c(colnames(tf),"total")
tf2
## consumidor produtor escola outras total
## SP 214 237 78 119 648
## PR 51 102 126 22 301
## RS 111 304 139 48 602
## total 376 643 343 189 1551
is.matrix(tf2)
## [1] TRUE
| consumidor | produtor | escola | outras | total | |
|---|---|---|---|---|---|
| SP | 214 | 237 | 78 | 119 | 648 |
| PR | 51 | 102 | 126 | 22 | 301 |
| RS | 111 | 304 | 139 | 48 | 602 |
| total | 376 | 643 | 343 | 189 | 1551 |
Uma tabela de frequências relativas de dupla entrada para as variáveis estado e tipo de cooperativa pode ser construída com um dos seguintes scripts.
#
# Script 1
#
tf.p <- (tf/sum(tf))
tf3 <- (tf.p)*100
tf3 <- addmargins(tf3)
rownames(tf3) <- c(rownames(tf),"total")
colnames(tf3) <- c(colnames(tf),"total")
round(tf3,1)
##
## consumidor produtor escola outras total
## SP 13.8 15.3 5.0 7.7 41.8
## PR 3.3 6.6 8.1 1.4 19.4
## RS 7.2 19.6 9.0 3.1 38.8
## total 24.2 41.5 22.1 12.2 100.0
#
# Alternativamente, script 2
#
tf4 <- (tf.p)*100
tf4 <- rbind(cbind(tf4,apply(tf4,1,sum)),apply(cbind(tf4,apply(tf4,1,sum)),2,sum))
rownames(tf4) <- c(rownames(tf),"total")
colnames(tf4) <- c(colnames(tf),"total")
round(tf4,1)
## consumidor produtor escola outras total
## SP 13.8 15.3 5.0 7.7 41.8
## PR 3.3 6.6 8.1 1.4 19.4
## RS 7.2 19.6 9.0 3.1 38.8
## total 24.2 41.5 22.1 12.2 100.0
Uma tabela de frequências relativas condicionais de dupla entrada para
as variáveis estado e tipo de
cooperativa pode ser construída utilizando a função
prop.table(). O segundo argumento desta função indica se
frequências relativas condicionais devem ser calculadas em relação aos
totais marginais das linhas (se margin=1) ou se frequências
relativas condicionais devem ser calculadas em relação aos totais
marginais das colunas (se margin=2).
tf5 <- prop.table(tf,margin=1)
round(tf5*100,1)
##
## consumidor produtor escola outras
## SP 33.0 36.6 12.0 18.4
## PR 16.9 33.9 41.9 7.3
## RS 18.4 50.5 23.1 8.0
tf5 <- rbind(tf5,margin.table(tf,2)/sum(tf))
tf5 <- cbind(tf5,margin.table(tf5,1))
rownames(tf5) <- c(rownames(tf),"total")
colnames(tf5) <- c(colnames(tf),"total")
round(tf5*100,1)
## consumidor produtor escola outras total
## SP 33.0 36.6 12.0 18.4 100
## PR 16.9 33.9 41.9 7.3 100
## RS 18.4 50.5 23.1 8.0 100
## total 24.2 41.5 22.1 12.2 100
A função barplot() também pode ser usada para construir
gráficos de barras a partir de tabelas de frequências de dupla entrada,
quer sejam frequências absolutas, relativas ou relativas condicionais.
Como exemplo, considere o conjunto de dados bivariado desta seção
envolvendo as variáveis estado e tipo de
cooperativa.
tf
##
## consumidor produtor escola outras
## SP 214 237 78 119
## PR 51 102 126 22
## RS 111 304 139 48
t(tf)
##
## SP PR RS
## consumidor 214 51 111
## produtor 237 102 304
## escola 78 126 139
## outras 119 22 48
cores <- c("blue","red","green","yellow")
legenda <- c("Consumidor","Produtor","Escola","Outras")
barplot(t(tf),col=cores,ylab="Frequência",ylim=c(0,700))
legend(1.45,645,legend=legenda,fill=cores)
round(100*prop.table(tf,1),1)
##
## consumidor produtor escola outras
## SP 33.0 36.6 12.0 18.4
## PR 16.9 33.9 41.9 7.3
## RS 18.4 50.5 23.1 8.0
round(100*t(prop.table(tf,1)),1)
##
## SP PR RS
## consumidor 33.0 16.9 18.4
## produtor 36.6 33.9 50.5
## escola 12.0 41.9 23.1
## outras 18.4 7.3 8.0
cores <- c("blue","red","green","yellow")
legenda <- c("Consumidor","Produtor","Escola","Outras")
barplot(t(prop.table(tf,1)),col=cores,ylab="Frequência relativa condicional",ylim=c(0,1))
legend(1.45,0.86,legend=legenda,fill=cores)
dev.off()
## null device
## 1
A função chisq.test() pode ser utilizada para realiza o
seguinte teste de hipóteses envolvendo duas variáveis categóricas: \[
\begin{cases}
H_{0}: & \mbox{$X$ e $Y$ são independentes} \\
H_{1}: & \mbox{$X$ e $Y$ não são independentes} \\
& \mbox{($X$ e $Y$ estão associadas)}
\end{cases}
\] Como exemplo, considere o conjunto de dados bivariado desta
seção envolvendo as variáveis estado e tipo de
cooperativa. Se \(X\)
representa estado e \(Y\) representa tipo de
cooperativa, podemos usar a função chisq.test()
para testar se estado e tipo de
cooperativa são variáveis independentes. O resultado deste
teste mostra que não existem evidências nos dados que suportam a
hipótese nula \(H_{0}\) de
independência entre as variáveis (observe que o p-value do
teste é muito pequeno). Isto significa que existe associação (ou
dependência) entre as variáveis estado e tipo
de cooperativa. Em outras palavras, existem evidências nos
dados que o tipo de cooperativa depende do
estado (ou seja, da localização).
tf
##
## consumidor produtor escola outras
## SP 214 237 78 119
## PR 51 102 126 22
## RS 111 304 139 48
round(100*prop.table(tf,1),1)
##
## consumidor produtor escola outras
## SP 33.0 36.6 12.0 18.4
## PR 16.9 33.9 41.9 7.3
## RS 18.4 50.5 23.1 8.0
round(100*prop.table(tf,2),1)
##
## consumidor produtor escola outras
## SP 56.9 36.9 22.7 63.0
## PR 13.6 15.9 36.7 11.6
## RS 29.5 47.3 40.5 25.4
chisq.test(tf)
##
## Pearson's Chi-squared test
##
## data: tf
## X-squared = 173.38, df = 6, p-value < 2.2e-16
O resultado que o tipo de cooperativa depende do estado está em concordância com a análise gráfica. Se estado e tipo de cooperativa fossem variáveis independentes, a distribuição de frequências relativas do tipo de cooperativa condicionada ao estado não iria variar significativamente com a localidade. O que observamos no seguinte gráfico é exatamente o contrário. De fato, o gráfico mostra que a distribuição de frequências relativas do tipo de cooperativa condicionada ao estado varia significativamente com a localidade.
## null device
## 1
Nesta seção conside o seguinte conjunto de dados bivariado, extraído do Capítulo 4 da referência Morettin & Bussab (2010). A variável \(x\) representa a renda bruta familiar mensal e a variável \(y\) representa a porcentagem da renda bruta familiar mensal que é gasta com saúde. Estamos interessados em verificar se a variável \(y\) pode ser explicada em função da variável \(x\) através de um modelo linear definido por: \[ \hat{y}=\hat{a}+\hat{b}x \] onde \(\hat{a}\) e \(\hat{b}\) são os parâmetros estimados do modelo (estimados a partir dos dados) e \(\hat{y}\) é o valor predito para a porcentagem da renda bruta familiar mensal que é gasta com saúde para um dado valor \(x\) da renda bruta familiar mensal. Os dados são:
# x: renda bruta familiar mensal
x <- c(12,16,18,20,28,30,40,48,50,54)
# y: porcentagem da renda bruta familiar mensal gasta com saúde
y <- c(7.2,7.4,7.0,6.5,6.6,6.7,6.0,5.6,6.0,5.5)
f <- LETTERS[1:10]
df2a <- data.frame(Familia=f,x,y)
df2a
## Familia x y
## 1 A 12 7.2
## 2 B 16 7.4
## 3 C 18 7.0
## 4 D 20 6.5
## 5 E 28 6.6
## 6 F 30 6.7
## 7 G 40 6.0
## 8 H 48 5.6
## 9 I 50 6.0
## 10 J 54 5.5
is.data.frame(df2a)
## [1] TRUE
str(df2a)
## 'data.frame': 10 obs. of 3 variables:
## $ Familia: chr "A" "B" "C" "D" ...
## $ x : num 12 16 18 20 28 30 40 48 50 54
## $ y : num 7.2 7.4 7 6.5 6.6 6.7 6 5.6 6 5.5
| Familia | x | y |
|---|---|---|
| A | 12 | 7.2 |
| B | 16 | 7.4 |
| C | 18 | 7.0 |
| D | 20 | 6.5 |
| E | 28 | 6.6 |
| F | 30 | 6.7 |
| G | 40 | 6.0 |
| H | 48 | 5.6 |
| I | 50 | 6.0 |
| J | 54 | 5.5 |
Considere o conjunto de dados desta seção. Podemos visualizar este
conjunto de dados através de um gráfico chamado de gráfico de dispersão.
Este gráfico pode ser construído utilizando a função plot()
conforme o script que segue.
#
# Para construir o gráfico de dispersão não
# necessitaremos da coluna Familia. Sendo
# assim, vamos considerar apenas as colunas
# correspondentes às variáveis x e y.
#
df2 <- df2a[,-1]
df2
## x y
## 1 12 7.2
## 2 16 7.4
## 3 18 7.0
## 4 20 6.5
## 5 28 6.6
## 6 30 6.7
## 7 40 6.0
## 8 48 5.6
## 9 50 6.0
## 10 54 5.5
plot(df2$x,df2$y,type="p",xlim=c(10,60),ylim=c(4,9),xlab="Renda bruta mensal",ylab="% Gasto com saúde",pch=16)
dev.off()
## null device
## 1
O conjunto de dados desta seção pode ser visto como duas amostras
pareadas das variáveis \(x\) e \(y\), onde cada observação \(x_{i}\) na primeira amostra está pareada
com uma observação \(y_{i}\) da segunda
amostra, formando assim um par \((x_{i},y_{i})\) das variáveis \(x\) e \(y\), observado numa unidade experimental
que, neste caso, é uma família. Após o gráfico de dispersão dos dados,
outro passo importante que deve ser feito no estudo que desejamos
realizar nesta seção e verificar se existe associação linear entre as
variáveis \(x\) e \(y\). Como \(x\) e \(y\) são ambas variáveis numéricas, isto
pode ser feito calculando o coeficiente de correlação amostral (de
Pearson) definido por \[
r=\frac{\sum_{i}(x_{i}-\bar{x})(y_{i}-\bar{y})}
{\sqrt{\sum_{i}(x_{i}-\bar{x})^{2}\cdot\sum_{i}(y_{i}-\bar{y})^{2}}}
\] que é um estimador do coeficiente de correlação populacional
entre \(x\) e \(y\), definido por \[
\rho=\rho(x,y)=\frac{Cov(x,y)}{\sigma_{x}\cdot\sigma_{y}}
\] e geralmente desconhecido. Além disso, o seguinte teste de
hipóteses deve ser realizado: \[
\begin{cases}
H_{0}: & \rho=0\hspace{0.5cm}(\mbox{Não existe correlação entre $x$
e $y$})\\
H_{1}: & \rho\not=0 \hspace{0.5cm}(\mbox{Existe correlação entre $x$
e $y$}).
\end{cases}
\] O seguinte script porporciona funções para calcular \(r\) (a função cor()) e testar
\(H_{0}:\rho=0\) (a função
cor.test()).
summary(df2)
## x y
## Min. :12.0 Min. :5.500
## 1st Qu.:18.5 1st Qu.:6.000
## Median :29.0 Median :6.550
## Mean :31.6 Mean :6.450
## 3rd Qu.:46.0 3rd Qu.:6.925
## Max. :54.0 Max. :7.400
c(var(df2$x),var(df2$y))
## [1] 238.0444444 0.4316667
c(sd(df2$x),sd(df2$y))
## [1] 15.4286890 0.6570134
cov(df2$x,df2$y)
## [1] -9.533333
cor(df2$x,df2$y)
## [1] -0.9404625
cov(df2)
## x y
## x 238.044444 -9.5333333
## y -9.533333 0.4316667
cor(df2,method="pearson")
## x y
## x 1.0000000 -0.9404625
## y -0.9404625 1.0000000
cor.test(df2$x,df2$y,method="pearson")
##
## Pearson's product-moment correlation
##
## data: df2$x and df2$y
## t = -7.826, df = 8, p-value = 5.114e-05
## alternative hypothesis: true correlation is not equal to 0
## 95 percent confidence interval:
## -0.9861500 -0.7621149
## sample estimates:
## cor
## -0.9404625
Os resultados mostram que \(r=\hat{\rho}=-0.9404625\). Ou seja, a
variável renda bruta familiar mensal é fortemente
correlacionada como a variável porcentagem da renda bruta
familiar mensal gasta com saúde e esta correlação é negativa,
que significa que quanto maior for a renda bruta menor será a
porcentagem da renda bruta gasta com saúde e vice-versa. Além disso, o
resultado do teste mostra que não existem evidências nos dados que
suportam a hipótese \(H_{0}\) de
correlação nula (independência entre as variáveis supondo normalidade).
Observe que o p-value do teste é muito pequeno. Isto
significa que a correlação linear (ou associação linear ou dependência
linear) entre as variáveis renda bruta familiar mensal
e porcentagem da renda bruta familiar mensal gasta com
saúde é estatisticamente significativa.
Como existe uma correlação estatisticamente significativa entre as
variáveis renda bruta familiar mensal (representada por
\(x\)) e porcentagem da renda
bruta familiar mensal gasta com saúde (representada por \(y\)), estamos agora interessados em
construir o modelo linear definido por: \[
\hat{y}=\hat{a}+\hat{b}x
\] onde \(\hat{a}\) e \(\hat{b}\) são parâmetros estimados do
modelo e \(\hat{y}\) é o valor predito
para a porcentagem da renda bruta familiar mensal que é gasta com saúde
para um dado valor \(x\) da renda bruta
familiar mensal. Podemos usar a função lm() para
desenvolver este modelo, conforme o seguinte script.
modelo <- lm(y~x,data=df2)
summary(modelo)
##
## Call:
## lm(formula = y ~ x, data = df2)
##
## Residuals:
## Min 1Q Median 3Q Max
## -0.41456 -0.09842 -0.01481 0.14090 0.32524
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 7.715534 0.178214 43.294 8.94e-11 ***
## x -0.040049 0.005117 -7.826 5.11e-05 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.2369 on 8 degrees of freedom
## Multiple R-squared: 0.8845, Adjusted R-squared: 0.87
## F-statistic: 61.25 on 1 and 8 DF, p-value: 5.114e-05
anova(modelo)
## Analysis of Variance Table
##
## Response: y
## Df Sum Sq Mean Sq F value Pr(>F)
## x 1 3.4362 3.4362 61.246 5.114e-05 ***
## Residuals 8 0.4488 0.0561
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
plot(df2,type="p",xlim=c(10,60),ylim=c(4,9),xlab="Renda bruta mensal",ylab="% Gasto com saúde",pch=16)
abline(modelo,col="red")
dev.off()
## null device
## 1
Os resultados mostram que o modelo estimado é dado por: \[
\hat{y}=7.715534-0.040049x.
\] Este modelo está representado pela linha vermelha no gráfico
acima e pode ser aplicado para proporcionar um valor predito para a
porcentagem da renda bruta familiar mensal que é gasta com saúde para um
dado valor \(x\) da renda bruta
familiar mensal inicialmente não observada nos dados. Por exemplo,
digamos que queremos prever a porcentagem da renda bruta familiar mensal
que é gasta com saúde para o valor \(x=33\) de renda bruta familiar mensal.
Manualmente, basta fazer a seguinte conta: \[
\hat{y}=7.715534-0.040049(33)=6.393917.
\] Alternativamente, esta predição pode ser feita automática
utilizando a função predict().
predict(modelo,data.frame(x=33))
## 1
## 6.393932
#
# Se desejar predições para diversos valores ao mesmo tempo
#
predict(modelo,data.frame(x=c(23,33,43)))
## 1 2 3
## 6.794417 6.393932 5.993447
#
# Note que também
#
names(modelo)
## [1] "coefficients" "residuals" "effects" "rank"
## [5] "fitted.values" "assign" "qr" "df.residual"
## [9] "xlevels" "call" "terms" "model"
coefficients(modelo)
## (Intercept) x
## 7.71553398 -0.04004854
x0 <- c(23,33,43)
y.hat <- coefficients(modelo)[1]+coefficients(modelo)[2]*x0
y.hat
## [1] 6.794417 6.393932 5.993447
Nesta seção considere novamente o conjunto de dados utilizado nas quatro primeiras seções deste material. Particularmente, aqui nesta seção, estamos interessados no conjunto de dados bivariado envolvendo as variáveis grau de instrução e salário. Este conjunto de dados contém, portanto, uma variável categórica e outra numérica. Os dados são:
df3 <- subset(df,select=c("grau_instrucao","salario"))
colnames(df3) <- c("Grau_instrucao","Salario")
levels(df3$Grau_instrucao) <- c("Fundamental","Medio","Superior")
str(df3)
## 'data.frame': 36 obs. of 2 variables:
## $ Grau_instrucao: Ord.factor w/ 3 levels "Fundamental"<..: 1 1 1 2 1 1 1 1 2 2 ...
## $ Salario : num 4 4.56 5.25 5.73 6.26 6.66 6.86 7.39 7.59 7.44 ...
head(df3)
## Grau_instrucao Salario
## 1 Fundamental 4.00
## 2 Fundamental 4.56
## 3 Fundamental 5.25
## 4 Medio 5.73
## 5 Fundamental 6.26
## 6 Fundamental 6.66
Nossa análise se torna mais fácil se ordenarmos os dados conforme os níveis da variável grau de instrução.
f <- which(df3$Grau_instrucao==levels(df3$Grau_instrucao)[1])
m <- which(df3$Grau_instrucao==levels(df3$Grau_instrucao)[2])
s <- which(df3$Grau_instrucao==levels(df3$Grau_instrucao)[3])
df3o <- df3[c(f,m,s),]
df3o
## Grau_instrucao Salario
## 1 Fundamental 4.00
## 2 Fundamental 4.56
## 3 Fundamental 5.25
## 5 Fundamental 6.26
## 6 Fundamental 6.66
## 7 Fundamental 6.86
## 8 Fundamental 7.39
## 12 Fundamental 8.46
## 14 Fundamental 8.95
## 18 Fundamental 9.80
## 23 Fundamental 12.00
## 27 Fundamental 13.85
## 4 Medio 5.73
## 9 Medio 7.59
## 10 Medio 7.44
## 11 Medio 8.12
## 13 Medio 8.74
## 15 Medio 9.13
## 16 Medio 9.35
## 17 Medio 9.77
## 20 Medio 10.76
## 21 Medio 11.06
## 22 Medio 11.59
## 25 Medio 13.23
## 26 Medio 13.60
## 28 Medio 14.69
## 29 Medio 14.71
## 30 Medio 15.99
## 32 Medio 16.61
## 35 Medio 19.40
## 19 Superior 10.53
## 24 Superior 12.79
## 31 Superior 16.22
## 33 Superior 17.26
## 34 Superior 18.75
## 36 Superior 23.30
Podemos usar a função boxplot() para obter uma visualização
gráfica deste conjunto de dados.
boxplot(df3o$Salario~df3o$Grau_instrucao,
xlab="Grau de instrução",ylab="Salário",
col=c("lightblue","lightsalmon","lightgreen"))
Sintese numérica por ser obtida como segue:
n <- as.vector(c(table(df3o$Grau_instrucao),sum(table(df3o$Grau_instrucao))))
todos <- as.vector(summary(df3o$Salario))
g.f <- summary(subset(df3o,subset=Grau_instrucao==levels(df3o$Grau_instrucao)[1])$Salario)
g.m <- summary(subset(df3o,subset=Grau_instrucao==levels(df3o$Grau_instrucao)[2])$Salario)
g.s <- summary(subset(df3o,subset=Grau_instrucao==levels(df3o$Grau_instrucao)[3])$Salario)
g.f <- as.vector(g.f);g.m <- as.vector(g.m);g.s <- as.vector(g.s)
dp.f <- sd(subset(df3o,subset=Grau_instrucao==levels(df3o$Grau_instrucao)[1])$Salario)
dp.m <- sd(subset(df3o,subset=Grau_instrucao==levels(df3o$Grau_instrucao)[2])$Salario)
dp.s <- sd(subset(df3o,subset=Grau_instrucao==levels(df3o$Grau_instrucao)[3])$Salario)
dp.t <- sd(df3o$Salario)
dp <- c(dp.f,dp.m,dp.s,dp.t);var <- dp^(2)
resumo <- data.frame(Fundamental=g.f,Médio=g.m,Superior=g.s,Todos=todos)
resumo <- rbind(n,resumo,var,dp)
rownames(resumo) <- c("n","Min","Q1","Mediana","Média","Q3","Máx","Variância","Desvio Padrão")
resumo
## Fundamental Médio Superior Todos
## n 12.000000 18.000000 6.000000 36.000000
## Min 4.000000 5.730000 10.530000 4.000000
## Q1 6.007500 8.837500 13.647500 7.552500
## Mediana 7.125000 10.910000 16.740000 10.165000
## Média 7.836667 11.528333 16.475000 11.122222
## Q3 9.162500 14.417500 18.377500 14.060000
## Máx 13.850000 19.400000 23.300000 23.300000
## Variância 8.740679 13.802297 20.271950 21.044766
## Desvio Padrão 2.956464 3.715144 4.502438 4.587458