Vamos utilizar aqui o conjunto de dados milsa de Bussab & Morettin discutidos na Seção 8.2 e que pode ser obtido conforme comando a seguir. Repetimos aqui o preparo inicial dos dados convertendo as variáveis categóricas em fatores do R e criando a variável idade a partir de ano e mes.
> milsa <- read.table("http://www.leg.ufpr.br/Rembrapa/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 nos cruzamentos de variáveis. A seguir mostramos algumas opções da visualizaçã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. A classe do objeto resultante vai depender da função utilizada. Nesse 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 estão 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)
[1] "table" "ftable"
> sapply(list(t1, t1f), is.matrix)
[1] TRUE TRUE
> sapply(list(t1, t1f), is.array)
[1] TRUE TRUE
Ambas funções possuem o argumento dnn que pode ser usado para sobrescrever os nomes das dimensões do objeto resultante.
> dimnames(t1)
$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 <- ftable(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 entre 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
O objeto retornado por table() não é uma matriz, mas sim um array de três dimensões, por serem três variáveis. A dimensão do array é de \(2\times 3\times 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\times 3\) onde \(6=2\times 3\) indicando o produto do número de níveis das duas primeiras variáveis.
> sapply(list(t2,t2f), is.matrix)
[1] FALSE TRUE
> sapply(list(t2,t2f), is.array)
[1] TRUE TRUE
> 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 matriz de dimensão \(6\times 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
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 apenas 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 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 classes. Da mesma forma, no caso de duas variáveis, as margens das tabelas obtidas de uma ou outra forma são as mesmas. O valor numérico retornado por margin.table() é idêntico para t1 e t1f, ainda que, em versões recentes do R, imprimir o resultado de margin.table() aplicado a um ftable totalmente colapsado (reduzido a uma única dimensão) provoque um erro interno em print.ftable(); por isso abaixo mostramos a impressão apenas para o objeto t1.
> prop.table(t1)
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(t1f)
instrucao 1oGrau 2oGrau Superior civil 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)
instrucao 1oGrau 2oGrau Superior civil 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) produz o mesmo resultado numérico de > ## margin.table(t1, mar=1), mas sua impressão falha em versões > ## recentes do R devido a um problema em print.ftable() ao lidar > ## com um ftable de uma única dimensão. > margin.table(t1, mar=2)
Nível de Instrução 1oGrau 2oGrau Superior 12 18 6
> ## margin.table(t1f, mar=2) -- mesma limitação de impressão acima.
Da mesma forma os gráficos obtidos são os mesmos. A Figura 14 mostra dois tipos de gráficos. Os gráficos na parte superior mostram retângulos cujas áreas são proporcionais às frequências e abaixo um dentre os possíveis gráficos de barras.
> plot(t1, main="") > plot(t1f, main="") > barplot(t1, beside=T, legend=T) > barplot(t1f, beside=T, legend=T)
Já para três ou 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.
> prop.table(t2)
, , 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
> prop.table(t2f)
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 ftable()!
> 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)