3.10 Mais sobre data frames

Chegou a hora de usarmos tudo o que aprendemos na seção anterior para exploramos ao máximo o nosso objeto favorito: o data frame.

Na seção anterior, nós dissemos que data frames são listas. Isso é importante pois todas as propriedades de uma lista valem para um data frame.

A melhor forma de entender essa equivalência é ver um data frame representado como uma lista.

as.list(mtcars)
## $mpg
##  [1] 21.0 21.0 22.8 21.4 18.7 18.1 14.3 24.4 22.8 19.2 17.8 16.4 17.3 15.2 10.4
## [16] 10.4 14.7 32.4 30.4 33.9 21.5 15.5 15.2 13.3 19.2 27.3 26.0 30.4 15.8 19.7
## [31] 15.0 21.4
## 
## $cyl
##  [1] 6 6 4 6 8 6 8 4 4 6 6 8 8 8 8 8 8 4 4 4 4 8 8 8 8 4 4 4 8 6 8 4
## 
## $disp
##  [1] 160.0 160.0 108.0 258.0 360.0 225.0 360.0 146.7 140.8 167.6 167.6 275.8
## [13] 275.8 275.8 472.0 460.0 440.0  78.7  75.7  71.1 120.1 318.0 304.0 350.0
## [25] 400.0  79.0 120.3  95.1 351.0 145.0 301.0 121.0
## 
## $hp
##  [1] 110 110  93 110 175 105 245  62  95 123 123 180 180 180 205 215 230  66  52
## [20]  65  97 150 150 245 175  66  91 113 264 175 335 109
## 
## $drat
##  [1] 3.90 3.90 3.85 3.08 3.15 2.76 3.21 3.69 3.92 3.92 3.92 3.07 3.07 3.07 2.93
## [16] 3.00 3.23 4.08 4.93 4.22 3.70 2.76 3.15 3.73 3.08 4.08 4.43 3.77 4.22 3.62
## [31] 3.54 4.11
## 
## $wt
##  [1] 2.620 2.875 2.320 3.215 3.440 3.460 3.570 3.190 3.150 3.440 3.440 4.070
## [13] 3.730 3.780 5.250 5.424 5.345 2.200 1.615 1.835 2.465 3.520 3.435 3.840
## [25] 3.845 1.935 2.140 1.513 3.170 2.770 3.570 2.780
## 
## $qsec
##  [1] 16.46 17.02 18.61 19.44 17.02 20.22 15.84 20.00 22.90 18.30 18.90 17.40
## [13] 17.60 18.00 17.98 17.82 17.42 19.47 18.52 19.90 20.01 16.87 17.30 15.41
## [25] 17.05 18.90 16.70 16.90 14.50 15.50 14.60 18.60
## 
## $vs
##  [1] 0 0 1 1 0 1 0 1 1 1 1 0 0 0 0 0 0 1 1 1 1 0 0 0 0 1 0 1 0 0 0 1
## 
## $am
##  [1] 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 1 1 1 1 1 1 1
## 
## $gear
##  [1] 4 4 4 3 3 3 3 4 4 4 4 3 3 3 3 3 3 4 4 4 3 3 3 3 3 4 5 5 5 5 5 4
## 
## $carb
##  [1] 4 4 1 1 2 1 4 2 2 4 4 3 3 3 4 4 4 1 2 1 1 2 2 4 2 1 2 2 4 6 8 2

O código acima nos permite ver o data frame mtcars representado como uma lista. Veja que cada coluna da base se transforma em um elemento da lista. E o nome de cada coluna vira o nome de cada posição. Isso é interessante, pois podemos usar nos data frames as mesmas operações que aprendemos para listas.

Por exemplo, podemos usar o operador $ para acessar cada elemento da lista, isto é, cada coluna do data frame.

E assim como cada elemento de uma lista também é uma lista, cada elemento (coluna) de um data frame também é um *data frame.

Mas se data frames são listas, por que existe a classe data frame? Na verdade, data frames são um tipo especial de listas, que têm as seguintes propriedades:

  1. Todos os seus elementos (colunas) precisam ter o mesmo comprimento (número de linhas).

  2. Todos os seus elementos (colunas) precisam ser nomeados.

  3. Data frames têm 2 dimensões.

As propriedades (1) e (2) se devem ao formato das bases de dados. Elas são retangulares7 — observamos as mesmas variáveis (colunas) para todas as unidades amostrais (linhas)8 —, e precisam ter algum nome especificando as colunas.

Da mesma forma que podemos ver um data frame como uma lista, também podemos fazer o inverso.

Quando tivermos valores faltantes na nossa base (células vazias no Excel), eles serão representados por NA nos data frames.

Observe que não conseguimos transformar uma lista em data frame se os elementos da lista não tiverem o mesmo comprimento.

Transformar uma lista não nomeada em data frame é possível, mas o R cria nomes nada agradáveis para as colunas.

A propriedade (3) é atribuída aos data frames para que possamos aproveitar melhor dessa estrutura retangular dentro do R. Na prática, essas duas dimensões representam nada mais que as linhas e as colunas da base. Essa é a maior diferença entre uma lista e um data frame.

O resultado do código dim(mtcars) nos dá as seguintes informações:

  • O data frame mtcars tem duas dimensões (como todo data frame).

  • A primeira dimensão tem comprimento 32 e a segunda dimensão tem comprimento 11. Em outras palavras: a base mtcars tem 32 linhas e 11 colunas.

Veja a seguir que listas não têm dimensão.

Ter duas dimensões significa que devemos usar dois índices para acessar os valores de um data frame (fazer subsetting). Para isso, ainda usamos o colchete, mas agora com dois argumentos: [linha, coluna].

O código acima está nos devolvendo o valor presente na segunda linha da terceira coluna da base mtcars.

Também podemos pegar todos as linhas de uma coluna ou todas as colunas de uma linha deixando um dos argumentos vazio:

Por fim, lembrando que dento de cada coluna temos um vetor, podemos usar os testes lógicos para filtrar as linhas do nosso data frame conforme alguma regra.

O código mtcars$cyl == 4 nos diz em quais linhas estão os carros com 4 cilindros. Quando usamos o vetor de TRUE e FALSE resultante dentro do subsetting das linhas em mtcars[mtcars$cyl == 4, ], o R nos devolve todos as colunas dos carros com 4 cilindros. A regra é simples: linha com TRUE é retornada, linha com FALSE não.

Encerramos aqui a nossa primeira conversa sobre data frames para falar de outra estrutura muito importante dentro do R: as funções.

Exercícios

1. Quais códigos abaixo retornam um vetor com a coluna “mpg”do data frame “mtcars”?

  1. mtcars$mpg
  2. mtcars[ , 3]
  3. mtcars("mpg")
  4. mtcars[ , "mpg"]
  5. mtcars.mpg
  6. mtcars[ , 1]
  7. mtcars[1, 1]
  8. mpg$mtcars

  1. Também existem bases não retangulares, como dados de imagens por exemplos, mas não trataremos dessas estruturas neste livro.

  2. Mesmo quando uma variável não existe para uma unidade amostral, representamos esse valor como um missing


Curso-R