10 Análise descritiva de tabelas de contingência
10.1 Tabelas para dois ou mais fatores
Vamos utilizar aqui os dados milsa de Bussab & Morettin discutidos na Sessão 8.2 e que podem
ser obtidos conforme comando abaixo. Repetimos aqui o preparo inicial dos dados convertendo as
variáveis categóricas em fatores do R e criando a variável idade.
> milsa <- read.table("http://www.leg.ufpr.br/~paulojus/dados/milsa.dat",
+ head = T)
> milsa <- transform(milsa, civil = factor(civil, label = c("solteiro",
+ "casado"), levels = 1:2), instrucao = factor(instrucao, label = c("1oGrau",
+ "2oGrau", "Superior"), lev = 1:3, ord = T), regiao = factor(regiao,
+ label = c("capital", "interior", "outro"), lev = c(2, 1,
+ 3)))
> milsa <- transform(milsa, idade = ano + mes/12)
> names(milsa)
Tabelas de contingência podem ser obtidas com as frequências de ocorrência dos cruzamentos das
variáveis. A seguir mostramos algumas opções da vizualização dos resultados usando a função
table() e a função ftable(). As funções retornam as tabelas de contingência em um objeto que
pode ser uma matrix, no caso do cruzamento de duas variáveis, ou de forma mais geral, na forma de
um array, onde o número de dimensões é igual ao número de variáveis. Entretanto a classe
do objeto resultante vai depender da função utilizada. Neste caso, para o cruzamento
de apenas duas variáveis, os resultados são exibidos de forma semelhante. No exemplo
consideram-se as variáveis civil e instrucao que situadas nas colunas 2 e 3 do data-frame.
> t1 <- table(milsa[c(2, 3)])
> t1
instrucao
civil 1oGrau 2oGrau Superior
solteiro 7 6 3
casado 5 12 3
> t1f <- ftable(milsa[c(2, 3)])
> t1f
instrucao 1oGrau 2oGrau Superior
civil
solteiro 7 6 3
casado 5 12 3
> sapply(list(t1, t1f), class)
> sapply(list(t1, t1f), is.matrix)
> sapply(list(t1, t1f), is.array)
Ambas funções possuem o argumento dnn que pode ser usado para sobrescrever os nomes das
dimensões do objeto resultante.
$civil
[1] "solteiro" "casado"
$instrucao
[1] "1oGrau" "2oGrau" "Superior"
> t1 <- table(milsa[c(2, 3)], dnn = c("Estado Civil", "Nível de Instrução"))
> dimnames(t1)
$‘Estado Civil‘
[1] "solteiro" "casado"
$‘Nível de Instrução‘
[1] "1oGrau" "2oGrau" "Superior"
> t1f <- table(milsa[c(2, 3)], dnn = c("Estado Civil", "Nível de Instrução"))
As diferenças na forma de exibir os resultados são mais claras considerando-se o cruzamento de
três ou mais variáveis. Enquanto table() vai exibir um array da forma usual, mostrando as várias
camadas separadamente, ftable() irá arranjar a tabela de forma plana, em uma visualização mais
adequada para a leitura dos dados. Vamos considerar o cruzamento das variáveis civil, instrucao e
regiao situadas nas colunas 2, 3 e 8 do data-frame.
> t2 <- with(milsa, table(civil, instrucao, regiao))
> t2
, , regiao = capital
instrucao
civil 1oGrau 2oGrau Superior
solteiro 2 1 1
casado 2 4 1
, , regiao = interior
instrucao
civil 1oGrau 2oGrau Superior
solteiro 2 1 1
casado 1 6 1
, , regiao = outro
instrucao
civil 1oGrau 2oGrau Superior
solteiro 3 4 1
casado 2 2 1
> t2f <- with(milsa, ftable(civil, instrucao, regiao))
> t2f
regiao capital interior outro
civil instrucao
solteiro 1oGrau 2 2 3
2oGrau 1 1 4
Superior 1 1 1
casado 1oGrau 2 1 2
2oGrau 4 6 2
Superior 1 1 1
Enquanto que o objeto retornado por table() não é uma matrix, mas sim um array de três
dimensões, por serem três variáveis. A dimensão do array é de 2 × 3 × 3 por haver 2 estados civis, 3
níveis de instrução e 3 regiões. Já o objeto retornado por ftable() ainda é uma matriz, neste caso
de dimensão 6 × 3 onde 6 = 2 × 3 indicando o produto do número de nívies das duas primeiras
variáveis.
> sapply(list(t2, t2f), is.matrix)
> sapply(list(t2, t2f), is.array)
> sapply(list(t2, t2f), dim)
[[1]]
[1] 2 3 3
[[2]]
[1] 6 3
Com ftable() é possível ainda criar outras visualizações da tabela. Os argumentos row.vars e
col.vars podem ser usados para indicar quais variáveis serão colocadas nas linhas e colunas,
e em que ordem. No exemplo a seguir colocamos o estado civil e região de procedência
(variáveis 1 e 3) nas colunas da tabela e também modificamos o nome das dimensões
da tabela com o argumento dnn. O objeto resultante é uma matrix de dimensão 6 × 3.
> with(milsa, ftable(civil, instrucao, regiao, dnn = c("Estado Civil:",
+ "Nível de Instrução", "Procedência:"), col.vars = c(1,
+ 3)))
Estado Civil: solteiro casado
Procedência: capital interior outro capital interior outro
Nível de Instrução
1oGrau 2 2 3 2 1 2
2oGrau 1 1 4 4 6 2
Superior 1 1 1 1 1 1
10.2 Extensões: frequências relativas e gráficos
As funções table() e ftable() retornam objetos das classes table e ftable, respectivamente. A
partir de tais objetos, outras funções podem ser utilizadas tais como prop.table() para obtenção de
frequências relativas, ou barplot() para gráficos de barras. A distinção entre as classes não é
importante no caso de cruzamento entre duas variáveis. Entretanto para três ou mais variáveis os
resultados são bem diferentes, devido ao fato já mencionado de que table() retorna um array
de dimensão igual ao número de variáveis, enquanto que ftable() retorna sempre uma
matriz.
Considerando os exemplos da Seção anterior, vejamos primeiro os resultados de frequências
relativas para duas variáveis, que não diferem entre as clases. Da mesma forma, no caso de
duas variáveis, as margens da tabelas obtidas de uma ou outra forma são as mesmas.
Nível de Instrução
Estado Civil 1oGrau 2oGrau Superior
solteiro 0.19444444 0.16666667 0.08333333
casado 0.13888889 0.33333333 0.08333333
Nível de Instrução
Estado Civil 1oGrau 2oGrau Superior
solteiro 0.19444444 0.16666667 0.08333333
casado 0.13888889 0.33333333 0.08333333
> prop.table(t1, margin = 1)
Nível de Instrução
Estado Civil 1oGrau 2oGrau Superior
solteiro 0.4375 0.3750 0.1875
casado 0.2500 0.6000 0.1500
> prop.table(t1f, margin = 1)
Nível de Instrução
Estado Civil 1oGrau 2oGrau Superior
solteiro 0.4375 0.3750 0.1875
casado 0.2500 0.6000 0.1500
> margin.table(t1, mar = 1)
Estado Civil
solteiro casado
16 20
> margin.table(t1f, mar = 1)
Estado Civil
solteiro casado
16 20
> margin.table(t1, mar = 2)
Nível de Instrução
1oGrau 2oGrau Superior
12 18 6
> margin.table(t1f, mar = 2)
Nível de Instrução
1oGrau 2oGrau Superior
12 18 6
Da mesma forma os gráficos obtidos são os mesmos. A Figura 10.2 mostra dois tipos de gráficos.
Acima os gráficos mostram retângulos cojas áreas são proporcionais às frequências e abaixo um
possível gráfico de barras.
> plot(t1, main = "")
> plot(t1f, main = "")
> barplot(t1, beside = T, legend = T)
> barplot(t1f, beside = T, legend = T)
Já para três os mais variáveis os resultados são bem diferentes em particular para as frequências
marginais, uma vez que ftable() vai sempre retornar uma matriz e portanto só possuirá margens 1 e
2.
, , regiao = capital
instrucao
civil 1oGrau 2oGrau Superior
solteiro 0.05555556 0.02777778 0.02777778
casado 0.05555556 0.11111111 0.02777778
, , regiao = interior
instrucao
civil 1oGrau 2oGrau Superior
solteiro 0.05555556 0.02777778 0.02777778
casado 0.02777778 0.16666667 0.02777778
, , regiao = outro
instrucao
civil 1oGrau 2oGrau Superior
solteiro 0.08333333 0.11111111 0.02777778
casado 0.05555556 0.05555556 0.02777778
regiao capital interior outro
civil instrucao
solteiro 1oGrau 0.05555556 0.05555556 0.08333333
2oGrau 0.02777778 0.02777778 0.11111111
Superior 0.02777778 0.02777778 0.02777778
casado 1oGrau 0.05555556 0.02777778 0.05555556
2oGrau 0.11111111 0.16666667 0.05555556
Superior 0.02777778 0.02777778 0.02777778
> prop.table(t2, margin = 1)
, , regiao = capital
instrucao
civil 1oGrau 2oGrau Superior
solteiro 0.1250 0.0625 0.0625
casado 0.1000 0.2000 0.0500
, , regiao = interior
instrucao
civil 1oGrau 2oGrau Superior
solteiro 0.1250 0.0625 0.0625
casado 0.0500 0.3000 0.0500
, , regiao = outro
instrucao
civil 1oGrau 2oGrau Superior
solteiro 0.1875 0.2500 0.0625
casado 0.1000 0.1000 0.0500
> prop.table(t2f, margin = 1)
regiao capital interior outro
civil instrucao
solteiro 1oGrau 0.2857143 0.2857143 0.4285714
2oGrau 0.1666667 0.1666667 0.6666667
Superior 0.3333333 0.3333333 0.3333333
casado 1oGrau 0.4000000 0.2000000 0.4000000
2oGrau 0.3333333 0.5000000 0.1666667
Superior 0.3333333 0.3333333 0.3333333
> prop.table(t2, margin = 3)
, , regiao = capital
instrucao
civil 1oGrau 2oGrau Superior
solteiro 0.18181818 0.09090909 0.09090909
casado 0.18181818 0.36363636 0.09090909
, , regiao = interior
instrucao
civil 1oGrau 2oGrau Superior
solteiro 0.16666667 0.08333333 0.08333333
casado 0.08333333 0.50000000 0.08333333
, , regiao = outro
instrucao
civil 1oGrau 2oGrau Superior
solteiro 0.23076923 0.30769231 0.07692308
casado 0.15384615 0.15384615 0.07692308
É possível obter totais marginais com margin.table() a partir de um objeto resultante de
table() mas não para um objeto resultante de parftable()!
> margin.table(t2, mar = 1)
civil
solteiro casado
16 20
> margin.table(t2, mar = 2)
instrucao
1oGrau 2oGrau Superior
12 18 6
> margin.table(t2, mar = 3)
regiao
capital interior outro
11 12 13
Para gráficos nem todos os resultados são mais possíveis, plot() vai funcionar para a classe
table mas o resultado é inapropriado para ftable. Já barplot() irá funcionar apenas para ftable,
mas o resultado pode não ser satisfatório pois as barras irão mostrar as combinações de duas
variáveis.
> plot(t2, main = "")
> barplot(t2f, beside = T)