17  Pacote data.table

Status 🟦🟨🟨

O pacote data.table oferece estrutura para manipulação de bases de dados de forma mais rápida que a base do R. As estruturas de dados são chamadas de data tables e funcionam de forma similar a um data frame.

library(data.table)

df_aprovacoes <-
  readRDS('./data/aprovacoes_por_porte_de_empresa.RDS')

17.1 Criando um Data Table

17.1.1 Função data.table

A criação de um data table se dá de forma análoga a um data frame através da função data.table.

df_exemplo <- data.table(x = 1:10)
df_exemplo |> class()
[1] "data.table" "data.frame"

17.1.2 Função setDT

Também podemos criar um data table a partir de um data frame com o comando setDT ou com a função as.data.table.

df_aprovacoes_as <- as.data.table(df_aprovacoes)
df_aprovacoes_as |> class()
[1] "data.table" "data.frame"
df_aprovacoes <- setDT(df_aprovacoes)
df_aprovacoes |> class()
[1] "data.table" "data.frame"
identical(df_aprovacoes_as, df_aprovacoes)
[1] TRUE

As operações realizadas com data tables possuem sintaxe específica e bastante sucinta. As operações são feitas sobre a base de dados na seguinte forma:

base[ linhas, colunas, agregação ]

17.2 Filtrando Dados

De forma análogo a um data frame padrão, os filtros nas linhas ocorrem antes da vírgula e podem usar operadores lógicos e relacionais. Uma grande vantagem é que as colunas podem ser referenciadas apenas pelo seu nome, sem incluir o nome do objeto.

df_aprovacoes[ANO == 2022 & MES > 6, ]
     ANO   MES     MICRO   PEQUENA    MEDIA    GRANDE
   <int> <int>     <num>     <num>    <num>     <num>
1:  2022     7 1763.7773 3843.3850 3286.456  1873.511
2:  2022     8 2378.3861 4640.6140 3965.469  3147.633
3:  2022     9  874.7404 1198.8596 2163.194  4625.476
4:  2022    10  419.9439  932.4995 1970.361  9020.808
5:  2022    11  323.8321  828.8072 2259.412  7908.244
6:  2022    12  413.4742 1087.6930 3795.945 37107.079

17.3 Selecionando Colunas

Para seleção de colunas, podemos colocar o nome da coluna diretamente após a vírgula, porém o reotrno é dado em forma de vetor e não mantém a estrutura do data table.

df_aprovacoes[, GRANDE] |> 
  is.vector()
[1] TRUE
df_aprovacoes[, GRANDE] |> 
  is.data.table()
[1] FALSE

Para seleção mais robusta devem ser informadas as colunas dentro de uma lista, que pode ser abreviada por um ponto.

df_aprovacoes[, list(GRANDE)] |> 
  is.data.table()
[1] TRUE
# selecioanndo mais de uma coluna
df_aprovacoes[, list(GRANDE, PEQUENA)] |> 
  head(3)
     GRANDE PEQUENA
      <num>   <num>
1: 380.2330       0
2: 495.5282       0
3: 715.9591       0
# usando ponto
df_aprovacoes[, .(GRANDE, PEQUENA)] |> 
  head(3)
     GRANDE PEQUENA
      <num>   <num>
1: 380.2330       0
2: 495.5282       0
3: 715.9591       0

17.4 Alterando Variáveis

A criação/alteração de variáveis pode ser feita basicamente de duas formas: forma funcional ou LHS := RHS. Em ambas as formas as operações são feitas diretamente no próprio objeto, não exigindo o operador de atribuição <-.

17.4.1 Forma Funcional

Na forma funcional se faz o uso do operador := (assignment by reference), que deixa o código bastante limpo e reduzido, facilitando a leitura.

df_aprovacoes[, RAZAO_GRANDE_MICRO := GRANDE / MICRO]
df_aprovacoes[, RAZAO_GRANDE_MICRO] |> head()
[1] 2.959705 4.660361 3.052496 3.226267 2.278962 3.862450

É possível efetuar a atualização/criação de várias variáveis simultaneamente.

df_aprovacoes[, `:=`(RAZAO_GRANDE_PEQUENA = GRANDE / PEQUENA,
                     RAZAO_GRANDE_MEDIA = GRANDE/MEDIA)]

17.4.2 Forma LHS := RHS

Uma forma alternativa pode ser usada com dois “vetores”, um com as variáveis a serem criadas e outro com os valores a serem atribuídos.

df_aprovacoes2 <- copy(df_aprovacoes)
df_aprovacoes[, c('RAZAO_GRANDE_PEQUENA', 'RAZAO_GRANDE_MEDIA') :=
                     list(GRANDE / PEQUENA, GRANDE/MEDIA)]

identical(df_aprovacoes, df_aprovacoes2)
[1] TRUE

17.5 Agrupando

O agrupamento/agregação ocorre com o operador by. Exemplo com criação da média de valores aprovados para o porte MICRO por ano, sendo que o ano deve ser a partir de 2020.

df_aprovacoes[ANO > 2019, list(MEAN_MICRO = mean(MICRO)), by = ANO]
     ANO MEAN_MICRO
   <int>      <num>
1:  2020   536.0065
2:  2021   536.2352
3:  2022   662.1226
4:  2023   312.2800

17.6 Ordenando Dados

A função setorder permite ordenação da base de dados sem exigir atribuição como usado com R base (df <- df[order(df$var),]).

df_aprovacoes |> head()
     ANO   MES    MICRO PEQUENA    MEDIA   GRANDE RAZAO_GRANDE_MICRO
   <int> <int>    <num>   <num>    <num>    <num>              <num>
1:  1995     1 128.4699       0 10.18922 380.2330           2.959705
2:  1995     2 106.3283       0 16.21161 495.5282           4.660361
3:  1995     3 234.5488       0 13.69085 715.9591           3.052496
4:  1995     4 125.2196       0 16.44511 403.9919           3.226267
5:  1995     5 209.4168       0 20.88794 477.2529           2.278962
6:  1995     6 122.5179       0 23.86818 473.2194           3.862450
   RAZAO_GRANDE_PEQUENA RAZAO_GRANDE_MEDIA
                  <num>              <num>
1:                  Inf           37.31717
2:                  Inf           30.56625
3:                  Inf           52.29471
4:                  Inf           24.56609
5:                  Inf           22.84825
6:                  Inf           19.82637
setorder(df_aprovacoes, -ANO, MES)
df_aprovacoes |> head(n = 8)
     ANO   MES    MICRO   PEQUENA     MEDIA   GRANDE RAZAO_GRANDE_MICRO
   <int> <int>    <num>     <num>     <num>    <num>              <num>
1:  2023     1 235.2636  654.6506 1048.4110 1337.163           5.683680
2:  2023     2 528.9812 1639.7768 2111.9314 1088.138           2.057045
3:  2023     3 260.0790  647.7431 1546.9274 1843.952           7.089969
4:  2023     4 157.7072  501.0023 1190.8649 3445.090          21.844841
5:  2023     5 119.9866  519.2932 1797.9574 2222.737          18.524876
6:  2023     6 571.6626 1985.3709 3554.8101 6506.082          11.380983
7:  2022     1 293.7928  412.8598  826.2161 1182.581           4.025222
8:  2022     2 195.4029  571.3932  910.6876 1460.593           7.474776
   RAZAO_GRANDE_PEQUENA RAZAO_GRANDE_MEDIA
                  <num>              <num>
1:            2.0425595          1.2754186
2:            0.6635891          0.5152336
3:            2.8467333          1.1920093
4:            6.8763948          2.8929308
5:            4.2803128          1.2362571
6:            3.2770111          1.8302194
7:            2.8643651          1.4313220
8:            2.5561957          1.6038352

17.7 Encadeamento

Existe a possibilidade de operações encadeadas. Esta operações são úteis quando se deseja transforma uma variável recém criada, por exemplo.

df_aprovacoes3 <- copy(df_aprovacoes)
df_aprovacoes3[, `:=`(DATA_ATUAL = Sys.Date(),
                     ANO_ATUAL = format(DATA_ATUAL, '%y'))]
Error in eval(jsub, SDenv, parent.frame()): objeto 'DATA_ATUAL' não encontrado

Sem o encadeamento não é possível extrair o ano da variável DATA_ATUAL pois ela ainda não foi criada.

df_aprovacoes4 <- copy(df_aprovacoes)
df_aprovacoes4[, DATA_ATUAL := Sys.Date()][,
   ANO_ATUAL := format(DATA_ATUAL, '%y')]

O encadeamento é equivalente ao uso do pipe e o placeholder indicando o data table.

df_aprovacoes5 <- copy(df_aprovacoes)
df_aprovacoes5[, DATA_ATUAL := Sys.Date()] |> 
  _[, ANO_ATUAL := format(DATA_ATUAL, '%y')]

identical(df_aprovacoes4, df_aprovacoes5)
[1] TRUE

Dowle e Srinivasan (2023)

Última atualização: 11/10/2024 - 21:49:13