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)

  [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 <- 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)

  [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 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.

  > 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)

              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)


PIC


Figura 14: Representações gráficas de tabelas de contingência de duas variáveis obtidas pelas funções table() e ftable().


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.

  > 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 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)


PIC


Figura 15: Representações gráficas de tabelas de contingência de três variáveis obtidas pelas funções table() (esquerda) e ftable() (direita).