1 Introdução

Neste relatório vamos abordar algumas técnicas em R de pré-processamento de dados. Criaremos uma base de dados genérica afim de aplicar algumas funções e métodos de organização e limpeza de dados em um data frame. Utilizaremos a biblioteca dplyr com alguns recursos de seleção derivados da função select(). Para determinados procedimentos de seleção, organização ou limpeza dos dados podem haver diversas maneiras de se obter o mesmo resultado, cabe ao estatístico utilizar as funções e métodos de sua preferência. A intenção é otimizar as técnicas de programação para poupar tempo e esforço e gerar bons resultados.

Temas de estudo: Pré-processamento, funções aninhadas, função startsWith()/endsWith(), função ifelse(), função for(), operador pipe (%>%), R Markdown.

2 Data Frame

Criaremos um Data Frame genérico relacionado à pescaria, onde a variável IdPeixe é apenas o número de identificação de determinada espécie de peixe, Quantidade é a quantidade de peixes pescados, Média representa o tamanho médio em centímetros dos peixes pescados e Local é o local geográfico em que o peixe foi capturado. Colocaremos valores NA propositalmente no Data Frame para podermos tratá-los posteriormente. Toda vez que a base de dados é gerada novas informações são armazenadas, pois não nos interessa a interpretação analítica da base de dados e sim os procedimentos de pré-processamento.

IdPeixe = seq(1,20,1)
Quantidade = rbinom(20, 100, 0.20)
x = seq(1,10.5,0.5); nx = length(x); Média = sample(x, nx, replace = F)
y = c("Lago", "Rio", "Mar", "Lagoa"); Local = sample(y, nx, replace = T)

df = data.frame(IdPeixe, Quantidade, Média, Local)

df$Média= ifelse(df$Média<= 3, is.na(df$Média), df$Média)
df$Média[df$Média== 0] = NA

df$IdPeixe = as.character(df$IdPeixe); class(df$IdPeixe)
## [1] "character"
glimpse(df)
## Rows: 20
## Columns: 4
## $ IdPeixe    <chr> "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "1~
## $ Quantidade <int> 24, 17, 19, 18, 22, 13, 23, 23, 23, 21, 24, 27, 20, 20, 14,~
## $ Média      <dbl> 8.5, NA, 5.5, 6.0, 9.0, 8.0, 7.5, 4.5, NA, NA, 6.5, 10.5, 5~
## $ Local      <chr> "Lago", "Mar", "Rio", "Lago", "Mar", "Lago", "Lagoa", "Rio"~
IdPeixe Quantidade Média Local
1 24 8.5 Lago
2 17 NA Mar
3 19 5.5 Rio
4 18 6.0 Lago
5 22 9.0 Mar
6 13 8.0 Lago
7 23 7.5 Lagoa
8 23 4.5 Rio
9 23 NA Lago
10 21 NA Mar
11 24 6.5 Rio
12 27 10.5 Lago
13 20 5.0 Lagoa
14 20 4.0 Lagoa
15 14 3.5 Lago
16 18 9.5 Mar
17 20 NA Rio
18 23 10.0 Rio
19 21 7.0 Rio
20 21 NA Mar

3 Técnicas de Pré-processamento

3.1 Remover elementos NA e coluna(s) desnecessária(s)

Remover a coluna IdPeixe e remover todas as linhas com valores NA. Note que este procedimento remove informações de outras variáveis e consequentemente diminui nosso tamanho amostral. Procedimento recomendado principalmente se houver poucos valores NA na sua base de dados.

df = df[!is.na(df$Média),]
df$IdPeixe = NULL
nrow(df)
## [1] 15
Quantidade Média Local
1 24 8.5 Lago
3 19 5.5 Rio
4 18 6.0 Lago
5 22 9.0 Mar
6 13 8.0 Lago
7 23 7.5 Lagoa
8 23 4.5 Rio
11 24 6.5 Rio
12 27 10.5 Lago
13 20 5.0 Lagoa
14 20 4.0 Lagoa
15 14 3.5 Lago
16 18 9.5 Mar
18 23 10.0 Rio
19 21 7.0 Rio

3.2 Substituir elementos NA pela média

Substituir todos os valores NA pela média de todos os elementos restantes da variável Média. A média é uma estatística, portanto, uma função da amostra. Em inferência (ou estatística indutiva) consideramos a média amostral um estimador pontual para o parâmetro de interesse chamado de média populacional. A média é uma medida resumo de tendência central de uma amostra, observe que se a média for uma medida representativa dos dados não há problema substituir valores faltantes pela média dos demais valores. Esse método mantém as informações das outras variavéis e sua base de dados permanece com o mesmo tamanho amostral.

média = mean(df$Média[!is.na(df$Média)]);média
## [1] 7
df$Média = df$Média %>% is.na() %>% ifelse(média, df$Média)
df$IdPeixe = NULL
nrow(df)
## [1] 20
Quantidade Média Local
15 4.0 Mar
22 3.5 Lago
22 7.5 Lagoa
21 9.0 Lagoa
23 8.0 Mar
17 7.0 Lago
17 4.5 Lagoa
19 5.5 Lago
17 10.0 Lagoa
19 8.5 Lagoa
24 9.5 Mar
20 7.0 Lagoa
21 10.5 Rio
22 6.0 Rio
24 7.0 Mar
22 7.0 Rio
15 7.0 Lago
12 5.0 Lago
22 7.0 Lago
21 6.5 Lagoa

3.3 Alterando os nomes das classes das variáveis

Algumas bases de dados que geram informações em tempo real podem armazenar elementos com nomes diferentes, porém com o mesmo significado para a análise. Imagine que uma empresa reporta alertas de erros do servidor em tempo real e o que difere alguns elementos são geralmente datas e horários distintos gerados na mesma coluna. Com o auxílio das funções startsWith() e endsWith() conseguimos selecionar um grupo de caracteres para alterarmos ou padronizarmos nossa base de dados. Neste caso, utilizamos apenas a última letra do nome das classes da variável Local para realizarmos as alterações.

rm(list = ls())

IdPeixe = seq(1,20,1)
Quantidade = rbinom(20, 100, 0.20)
x = seq(1,10.5,0.5); nx = length(x); Média = sample(x, nx, replace = F)
y = c("Lago", "Rio", "Mar", "Lagoa"); Local = sample(y, nx, replace = T)

df = data.frame(IdPeixe, Quantidade, Média, Local)

df$IdPeixe = NULL

for (i in 1:3) {
  u = c("o", "a", "r")
  w = c("Água Doce", "Água Doce", "Água Salgada")
  
  df$Local = df$Local %>% endsWith(u[i]) %>% ifelse(w[i], df$Local)
}
Quantidade Média Local
13 4.5 Água Salgada
25 2.5 Água Doce
18 1.5 Água Salgada
26 1.0 Água Doce
17 5.5 Água Doce
20 7.5 Água Doce
19 8.0 Água Doce
23 6.0 Água Doce
22 9.5 Água Doce
18 10.5 Água Doce
21 6.5 Água Doce
22 10.0 Água Doce
26 2.0 Água Doce
15 3.0 Água Doce
22 8.5 Água Doce
14 3.5 Água Doce
15 5.0 Água Salgada
27 9.0 Água Salgada
22 4.0 Água Salgada
17 7.0 Água Doce

3.4 Adicionar nova(s) coluna(s)

Muitas vezes não queremos alterar uma coluna já existente e sim criar uma nova coluna contendo novas informações para a base de dados. Colunas criadas pelo pesquisador geralmente são formadas por classificações ou estatísticas, podem ser tanto variáveis aleatórias quantitativas quanto qualitativas.

rm(list = ls())

IdPeixe = seq(1,20,1)
Quantidade = rbinom(20, 100, 0.20)
x = seq(1,10.5,0.5); nx = length(x); Média = sample(x, nx, replace = F)
y = c("Lago", "Rio", "Mar", "Lagoa"); Local = sample(y, nx, replace = T)
Tipo = Local

df = data.frame(IdPeixe, Quantidade, Média, Local)

for (i in 1:3) {
  u = c("o", "a", "r")
  w = c("Água Doce", "Água Doce", "Água Salgada")
  Tipo = Tipo %>% endsWith(u[i]) %>% ifelse(w[i], Tipo)
}; df = cbind(df, Tipo)
IdPeixe Quantidade Média Local Tipo
1 20 10.5 Lago Água Doce
2 20 7.5 Lago Água Doce
3 16 4.5 Lago Água Doce
4 21 6.0 Lagoa Água Doce
5 18 2.0 Mar Água Salgada
6 15 1.5 Lago Água Doce
7 18 8.0 Lago Água Doce
8 17 5.5 Mar Água Salgada
9 20 3.5 Rio Água Doce
10 23 1.0 Lago Água Doce
11 21 4.0 Mar Água Salgada
12 23 9.0 Lago Água Doce
13 14 3.0 Mar Água Salgada
14 21 7.0 Mar Água Salgada
15 24 2.5 Rio Água Doce
16 26 10.0 Mar Água Salgada
17 18 6.5 Rio Água Doce
18 23 5.0 Mar Água Salgada
19 25 8.5 Lagoa Água Doce
20 19 9.5 Rio Água Doce

3.5 Filtrando a base de dados (Variável Qualitativa)

Separando a base de dados em dois grupos referentes ao tipo de água do peixe. Os peixes de água salgada pertencem ao Grupo 1 e os de água doce ao Grupo 2. Para esse procedimento vamos utilizar a função filter().

grupo1 = filter(df, df$Tipo == "Água Salgada")
grupo2 = filter(df, df$Tipo == "Água Doce")

3.5.1 Grupo 1

IdPeixe Quantidade Média Local Tipo
5 18 2.0 Mar Água Salgada
8 17 5.5 Mar Água Salgada
11 21 4.0 Mar Água Salgada
13 14 3.0 Mar Água Salgada
14 21 7.0 Mar Água Salgada
16 26 10.0 Mar Água Salgada
18 23 5.0 Mar Água Salgada

3.5.2 Grupo 2

IdPeixe Quantidade Média Local Tipo
1 20 10.5 Lago Água Doce
2 20 7.5 Lago Água Doce
3 16 4.5 Lago Água Doce
4 21 6.0 Lagoa Água Doce
6 15 1.5 Lago Água Doce
7 18 8.0 Lago Água Doce
9 20 3.5 Rio Água Doce
10 23 1.0 Lago Água Doce
12 23 9.0 Lago Água Doce
15 24 2.5 Rio Água Doce
17 18 6.5 Rio Água Doce
19 25 8.5 Lagoa Água Doce
20 19 9.5 Rio Água Doce

3.6 Filtrando a base de dados (Variável Quantitativa)

Podemos também utilizar a filtragem nativa do R. Neste caso, quantidades maiores ou iguais a 20 peixes pertencem ao Grupo 1 e quantidades menores que 20 peixes pertecem ao Grupo 2.

grupo1 = df[df$Quantidade >= 20,]
grupo2 = df[df$Quantidade < 20,]

3.6.1 Grupo 1

IdPeixe Quantidade Média Local Tipo
1 1 20 10.5 Lago Água Doce
2 2 20 7.5 Lago Água Doce
4 4 21 6.0 Lagoa Água Doce
9 9 20 3.5 Rio Água Doce
10 10 23 1.0 Lago Água Doce
11 11 21 4.0 Mar Água Salgada
12 12 23 9.0 Lago Água Doce
14 14 21 7.0 Mar Água Salgada
15 15 24 2.5 Rio Água Doce
16 16 26 10.0 Mar Água Salgada
18 18 23 5.0 Mar Água Salgada
19 19 25 8.5 Lagoa Água Doce

3.6.2 Grupo 2

IdPeixe Quantidade Média Local Tipo
3 3 16 4.5 Lago Água Doce
5 5 18 2.0 Mar Água Salgada
6 6 15 1.5 Lago Água Doce
7 7 18 8.0 Lago Água Doce
8 8 17 5.5 Mar Água Salgada
13 13 14 3.0 Mar Água Salgada
17 17 18 6.5 Rio Água Doce
20 20 19 9.5 Rio Água Doce

3.7 Encode das variáveis

Podemos, se necessário, transformar variáveis categóricas em numéricas ou vice e versa com o uso da função factor(). O nome desse procedimento chama-se encode, onde mudamos o tipo da variável. Este método pode ser utilizado para transformações de variáveis dicotômicas (Dummy; 1 ou 0; Sim ou Não), para correções necessárias ou procedimentos correlatos. Vamos considerar um experimento em que nosso sucesso (valor 1) seja capturar um peixe de água doce e nosso fracasso (valor 0) seja capturar um peixe de água salgada.

IdPeixe Quantidade Média Local Tipo
1 25 3.5 Mar Água Salgada
2 20 1.0 Lago Água Doce
3 26 10.0 Rio Água Doce
4 24 8.5 Rio Água Doce
5 19 9.0 Lago Água Doce
6 22 9.5 Mar Água Salgada
7 16 5.0 Mar Água Salgada
8 19 6.5 Rio Água Doce
9 28 6.0 Mar Água Salgada
10 15 7.5 Mar Água Salgada
11 20 10.5 Lago Água Doce
12 21 7.0 Mar Água Salgada
13 15 4.0 Lago Água Doce
14 24 5.5 Lago Água Doce
15 26 4.5 Mar Água Salgada
16 26 8.0 Mar Água Salgada
17 18 3.0 Rio Água Doce
18 24 2.5 Rio Água Doce
19 18 1.5 Lago Água Doce
20 22 2.0 Lago Água Doce
df$Tipo = factor(df$Tipo, levels = c("Água Doce", "Água Salgada"), labels = c( 1, 0))
IdPeixe Quantidade Média Local Tipo
1 25 3.5 Mar 0
2 20 1.0 Lago 1
3 26 10.0 Rio 1
4 24 8.5 Rio 1
5 19 9.0 Lago 1
6 22 9.5 Mar 0
7 16 5.0 Mar 0
8 19 6.5 Rio 1
9 28 6.0 Mar 0
10 15 7.5 Mar 0
11 20 10.5 Lago 1
12 21 7.0 Mar 0
13 15 4.0 Lago 1
14 24 5.5 Lago 1
15 26 4.5 Mar 0
16 26 8.0 Mar 0
17 18 3.0 Rio 1
18 24 2.5 Rio 1
19 18 1.5 Lago 1
20 22 2.0 Lago 1

4 Fechamento

Este relatório teve como intuito apenas documentar meus progressos nos estudos de estatística e programação em R. Dominar a etapa de pré-processamento dos dados é fundamental para realizar bons modelos.

Contato:
Linkedin: https://www.linkedin.com/in/bruno-de-lima-teles-57a246247/