Sessão para carregamento de bibliotecas, dados brutos e variaveis de suporte. e aplicamos as primeiras normalizações (Cidades, Coordenadas e Reviews).
Carregamento de bibliotecas, leitura dos arquivos CSV e definição das Expressões Regulares para estados.
# Carregamento de bibliotecas
library(readr)
library(dplyr)
library(lubridate)
library(stringr)
library(stringi)
library(skimr)
library(tidyr)
# Carregamento dos Datasets Brutos
customers <- read_csv("olist_customers_dataset.csv")
geolocation <- read_csv("olist_geolocation_dataset.csv")
order_items <- read_csv("olist_order_items_dataset.csv")
order_payments <- read_csv("olist_order_payments_dataset.csv")
order_reviews <- read_csv("olist_order_reviews_dataset.csv")
orders <- read_csv("olist_orders_dataset.csv")
products <- read_csv("olist_products_dataset.csv")
sellers <- read_csv("olist_sellers_dataset.csv")
category_translation <- read_csv("product_category_name_translation.csv")
# Definição de Regex para Estados do Brasil
brazil_states_regex <- "\\b(ac|ap|am|pa|ro|rr|to|al|ba|ce|ma|pb|pe|pi|rn|se|go|mt|ms|df|es|mg|rj|sp|pr|rs|sc)\\b"
regex_sudeste <- "\\b(sp|rj|mg|es)\\b"
regex_sul <- "\\b(pr|rs|sc)\\b"
regex_nordeste <- "\\b(ba|pe|ce|rn|pb|pi|al|se|ma)\\b"
regex_centro_oeste <- "\\b(go|mt|ms|df)\\b"
regex_norte <- "\\b(pa|am|ac|ro|rr|ap|to)\\b"
Visualização superficial da estrutura dos dados, tipos de variáveis e valores ausentes iniciais.
# Visualização superficial da estrutura
skim(customers)
| Name | customers |
| Number of rows | 99441 |
| Number of columns | 5 |
| _______________________ | |
| Column type frequency: | |
| character | 5 |
| ________________________ | |
| Group variables | None |
Variable type: character
| skim_variable | n_missing | complete_rate | min | max | empty | n_unique | whitespace |
|---|---|---|---|---|---|---|---|
| customer_id | 0 | 1 | 32 | 32 | 0 | 99441 | 0 |
| customer_unique_id | 0 | 1 | 32 | 32 | 0 | 96096 | 0 |
| customer_zip_code_prefix | 0 | 1 | 5 | 5 | 0 | 14994 | 0 |
| customer_city | 0 | 1 | 3 | 32 | 0 | 4119 | 0 |
| customer_state | 0 | 1 | 2 | 2 | 0 | 27 | 0 |
skim(geolocation)
| Name | geolocation |
| Number of rows | 1000163 |
| Number of columns | 5 |
| _______________________ | |
| Column type frequency: | |
| character | 3 |
| numeric | 2 |
| ________________________ | |
| Group variables | None |
Variable type: character
| skim_variable | n_missing | complete_rate | min | max | empty | n_unique | whitespace |
|---|---|---|---|---|---|---|---|
| geolocation_zip_code_prefix | 0 | 1 | 5 | 5 | 0 | 19015 | 0 |
| geolocation_city | 0 | 1 | 2 | 38 | 0 | 8010 | 0 |
| geolocation_state | 0 | 1 | 2 | 2 | 0 | 27 | 0 |
Variable type: numeric
| skim_variable | n_missing | complete_rate | mean | sd | p0 | p25 | p50 | p75 | p100 | hist |
|---|---|---|---|---|---|---|---|---|---|---|
| geolocation_lat | 0 | 1 | -21.18 | 5.72 | -36.61 | -23.60 | -22.92 | -19.98 | 45.07 | ▇▂▁▁▁ |
| geolocation_lng | 0 | 1 | -46.39 | 4.27 | -101.47 | -48.57 | -46.64 | -43.77 | 121.11 | ▁▇▁▁▁ |
skim(orders)
| Name | orders |
| Number of rows | 99441 |
| Number of columns | 8 |
| _______________________ | |
| Column type frequency: | |
| character | 3 |
| POSIXct | 5 |
| ________________________ | |
| Group variables | None |
Variable type: character
| skim_variable | n_missing | complete_rate | min | max | empty | n_unique | whitespace |
|---|---|---|---|---|---|---|---|
| order_id | 0 | 1 | 32 | 32 | 0 | 99441 | 0 |
| customer_id | 0 | 1 | 32 | 32 | 0 | 99441 | 0 |
| order_status | 0 | 1 | 7 | 11 | 0 | 8 | 0 |
Variable type: POSIXct
| skim_variable | n_missing | complete_rate | min | max | median | n_unique |
|---|---|---|---|---|---|---|
| order_purchase_timestamp | 0 | 1.00 | 2016-09-04 21:15:19 | 2018-10-17 17:30:18 | 2018-01-18 23:04:36 | 98875 |
| order_approved_at | 160 | 1.00 | 2016-09-15 12:16:38 | 2018-09-03 17:40:06 | 2018-01-19 11:36:13 | 90733 |
| order_delivered_carrier_date | 1783 | 0.98 | 2016-10-08 10:34:01 | 2018-09-11 19:48:28 | 2018-01-24 16:10:58 | 81018 |
| order_delivered_customer_date | 2965 | 0.97 | 2016-10-11 13:46:32 | 2018-10-17 13:22:46 | 2018-02-02 19:28:10 | 95664 |
| order_estimated_delivery_date | 0 | 1.00 | 2016-09-30 00:00:00 | 2018-11-12 00:00:00 | 2018-02-15 00:00:00 | 459 |
skim(products)
| Name | products |
| Number of rows | 32951 |
| Number of columns | 9 |
| _______________________ | |
| Column type frequency: | |
| character | 2 |
| numeric | 7 |
| ________________________ | |
| Group variables | None |
Variable type: character
| skim_variable | n_missing | complete_rate | min | max | empty | n_unique | whitespace |
|---|---|---|---|---|---|---|---|
| product_id | 0 | 1.00 | 32 | 32 | 0 | 32951 | 0 |
| product_category_name | 610 | 0.98 | 3 | 46 | 0 | 73 | 0 |
Variable type: numeric
| skim_variable | n_missing | complete_rate | mean | sd | p0 | p25 | p50 | p75 | p100 | hist |
|---|---|---|---|---|---|---|---|---|---|---|
| product_name_lenght | 610 | 0.98 | 48.48 | 10.25 | 5 | 42 | 51 | 57 | 76 | ▁▁▃▇▁ |
| product_description_lenght | 610 | 0.98 | 771.50 | 635.12 | 4 | 339 | 595 | 972 | 3992 | ▇▃▁▁▁ |
| product_photos_qty | 610 | 0.98 | 2.19 | 1.74 | 1 | 1 | 1 | 3 | 20 | ▇▁▁▁▁ |
| product_weight_g | 2 | 1.00 | 2276.47 | 4282.04 | 0 | 300 | 700 | 1900 | 40425 | ▇▁▁▁▁ |
| product_length_cm | 2 | 1.00 | 30.82 | 16.91 | 7 | 18 | 25 | 38 | 105 | ▇▅▂▁▁ |
| product_height_cm | 2 | 1.00 | 16.94 | 13.64 | 2 | 8 | 13 | 21 | 105 | ▇▂▁▁▁ |
| product_width_cm | 2 | 1.00 | 23.20 | 12.08 | 6 | 15 | 20 | 30 | 118 | ▇▃▁▁▁ |
skim(sellers)
| Name | sellers |
| Number of rows | 3095 |
| Number of columns | 4 |
| _______________________ | |
| Column type frequency: | |
| character | 4 |
| ________________________ | |
| Group variables | None |
Variable type: character
| skim_variable | n_missing | complete_rate | min | max | empty | n_unique | whitespace |
|---|---|---|---|---|---|---|---|
| seller_id | 0 | 1 | 32 | 32 | 0 | 3095 | 0 |
| seller_zip_code_prefix | 0 | 1 | 5 | 5 | 0 | 2246 | 0 |
| seller_city | 0 | 1 | 2 | 40 | 0 | 611 | 0 |
| seller_state | 0 | 1 | 2 | 2 | 0 | 23 | 0 |
skim(order_items)
| Name | order_items |
| Number of rows | 112650 |
| Number of columns | 7 |
| _______________________ | |
| Column type frequency: | |
| character | 3 |
| numeric | 3 |
| POSIXct | 1 |
| ________________________ | |
| Group variables | None |
Variable type: character
| skim_variable | n_missing | complete_rate | min | max | empty | n_unique | whitespace |
|---|---|---|---|---|---|---|---|
| order_id | 0 | 1 | 32 | 32 | 0 | 98666 | 0 |
| product_id | 0 | 1 | 32 | 32 | 0 | 32951 | 0 |
| seller_id | 0 | 1 | 32 | 32 | 0 | 3095 | 0 |
Variable type: numeric
| skim_variable | n_missing | complete_rate | mean | sd | p0 | p25 | p50 | p75 | p100 | hist |
|---|---|---|---|---|---|---|---|---|---|---|
| order_item_id | 0 | 1 | 1.20 | 0.71 | 1.00 | 1.00 | 1.00 | 1.00 | 21.00 | ▇▁▁▁▁ |
| price | 0 | 1 | 120.65 | 183.63 | 0.85 | 39.90 | 74.99 | 134.90 | 6735.00 | ▇▁▁▁▁ |
| freight_value | 0 | 1 | 19.99 | 15.81 | 0.00 | 13.08 | 16.26 | 21.15 | 409.68 | ▇▁▁▁▁ |
Variable type: POSIXct
| skim_variable | n_missing | complete_rate | min | max | median | n_unique |
|---|---|---|---|---|---|---|
| shipping_limit_date | 0 | 1 | 2016-09-19 00:15:34 | 2020-04-09 22:35:08 | 2018-01-26 13:59:35 | 93318 |
skim(order_payments)
| Name | order_payments |
| Number of rows | 103886 |
| Number of columns | 5 |
| _______________________ | |
| Column type frequency: | |
| character | 2 |
| numeric | 3 |
| ________________________ | |
| Group variables | None |
Variable type: character
| skim_variable | n_missing | complete_rate | min | max | empty | n_unique | whitespace |
|---|---|---|---|---|---|---|---|
| order_id | 0 | 1 | 32 | 32 | 0 | 99440 | 0 |
| payment_type | 0 | 1 | 6 | 11 | 0 | 5 | 0 |
Variable type: numeric
| skim_variable | n_missing | complete_rate | mean | sd | p0 | p25 | p50 | p75 | p100 | hist |
|---|---|---|---|---|---|---|---|---|---|---|
| payment_sequential | 0 | 1 | 1.09 | 0.71 | 1 | 1.00 | 1 | 1.00 | 29.00 | ▇▁▁▁▁ |
| payment_installments | 0 | 1 | 2.85 | 2.69 | 0 | 1.00 | 1 | 4.00 | 24.00 | ▇▂▁▁▁ |
| payment_value | 0 | 1 | 154.10 | 217.49 | 0 | 56.79 | 100 | 171.84 | 13664.08 | ▇▁▁▁▁ |
skim(order_reviews)
| Name | order_reviews |
| Number of rows | 99224 |
| Number of columns | 7 |
| _______________________ | |
| Column type frequency: | |
| character | 4 |
| numeric | 1 |
| POSIXct | 2 |
| ________________________ | |
| Group variables | None |
Variable type: character
| skim_variable | n_missing | complete_rate | min | max | empty | n_unique | whitespace |
|---|---|---|---|---|---|---|---|
| review_id | 0 | 1.00 | 32 | 32 | 0 | 98410 | 0 |
| order_id | 0 | 1.00 | 32 | 32 | 0 | 98673 | 0 |
| review_comment_title | 87658 | 0.12 | 1 | 26 | 0 | 4178 | 0 |
| review_comment_message | 58256 | 0.41 | 1 | 208 | 0 | 35743 | 18 |
Variable type: numeric
| skim_variable | n_missing | complete_rate | mean | sd | p0 | p25 | p50 | p75 | p100 | hist |
|---|---|---|---|---|---|---|---|---|---|---|
| review_score | 0 | 1 | 4.09 | 1.35 | 1 | 4 | 5 | 5 | 5 | ▂▁▁▃▇ |
Variable type: POSIXct
| skim_variable | n_missing | complete_rate | min | max | median | n_unique |
|---|---|---|---|---|---|---|
| review_creation_date | 0 | 1 | 2016-10-02 00:00:00 | 2018-08-31 00:00:00 | 2018-02-02 00:00:00 | 636 |
| review_answer_timestamp | 0 | 1 | 2016-10-07 18:32:28 | 2018-10-29 12:27:35 | 2018-02-04 22:41:47 | 98248 |
skim(category_translation)
| Name | category_translation |
| Number of rows | 71 |
| Number of columns | 2 |
| _______________________ | |
| Column type frequency: | |
| character | 2 |
| ________________________ | |
| Group variables | None |
Variable type: character
| skim_variable | n_missing | complete_rate | min | max | empty | n_unique | whitespace |
|---|---|---|---|---|---|---|---|
| product_category_name | 0 | 1 | 3 | 46 | 0 | 71 | 0 |
| product_category_name_english | 0 | 1 | 3 | 39 | 0 | 71 | 0 |
Padronização de nomes de cidades removendo acentos, caracteres especiais e inconsistências. (Ainda em andamento, tem muitas variações para normalizar).
Foi criaodum método para limpar caso a caso. >. obs: Muitos desses valores foram vistos manualmente, utilizando view com valores agrupados.
#' Função para Limpeza de Nomes de Cidades (ainda incompleta)
normalize_city <- function(cities) {
normalized_cities <- cities %>%
str_to_lower() %>% # 1. Converter para minúsculas
str_remove(., paste0("\\s+", brazil_states_regex, "$")) %>% # 2. Remover abreviações de estado no FINAL da string
str_replace(., ".+@.+\\..+", NA_character_) %>% # 3. Invalidar e-mails
str_extract(., "^[^/\\\\,]+") %>% # 4. Extrair apenas a parte ANTES de separadores como / , \
str_remove_all(., "\\(.*?\\)") %>% # 5. Remover texto entre parênteses
str_replace_all(., "d'|d´|d`", "d'") %>% # 6. Padronizar apóstrofos
str_remove_all(., "[\\.'ºª´\\^~]") %>% # 7. Remover pontuação e caracteres indesejados
str_remove_all(., "^[\\.]+") %>%
str_replace_all(., "-", " ") %>%
str_squish() # 8. Remover espaços extras
normalized_cities <- str_replace(
normalized_cities,
paste0("^", brazil_states_regex, "$"), NA_character_) # 9. Invalidar (NA) cidades que são APENAS abreviações de estado
normalized_cities[normalized_cities == ""] <- NA_character_ # 10. Substituir strings vazias por NA
return(normalized_cities)
}
# Aplicação da normalização nas tabelas relevantes
customers <- customers %>% mutate(customer_city = normalize_city(customer_city))
sellers <- sellers %>% mutate(seller_city = normalize_city(seller_city))
geolocation <- geolocation %>% mutate(geolocation_city = normalize_city(geolocation_city))
Pretendo usar mapas na análise e pra isso fui dar uma olhada nas coordenadas. Vi que para cada prefixo de cep, tem inúmeras coordenadas(o que realmente é padrão e faz sentido), porém para o mapa isso não fica legal, então pode ser interessante criar um “ponto médio” para cada prefixo de cep.
Primeiro vamos vizualizar como está…
# Podemos ver que cada zip_code tem inumeras coordenadas,
# precisamos de um ponto médio para cada zip_code ou o mapa vai ficar uma loucura...
geolocation_per_zip_code <- geolocation %>%
group_by(geolocation_zip_code_prefix) %>%
arrange(geolocation_zip_code_prefix)
print(head(geolocation_per_zip_code, 50))
## # A tibble: 50 × 5
## # Groups: geolocation_zip_code_prefix [3]
## geolocation_zip_code_prefix geolocation_lat geolocation_lng geolocation_city
## <chr> <dbl> <dbl> <chr>
## 1 01001 -23.54929 -46.63356 sao paulo
## 2 01001 -23.55050 -46.63434 sao paulo
## 3 01001 -23.55064 -46.63441 sao paulo
## 4 01001 -23.54970 -46.63391 sao paulo
## 5 01001 -23.55143 -46.63407 sao paulo
## 6 01001 -23.55050 -46.63434 sao paulo
## 7 01001 -23.55134 -46.63403 sao paulo
## 8 01001 -23.54978 -46.63396 são paulo
## 9 01001 -23.55134 -46.63403 sao paulo
## 10 01001 -23.55050 -46.63434 sao paulo
## # ℹ 40 more rows
## # ℹ 1 more variable: geolocation_state <chr>
Agora unificando as coordenadas por CEP e utilizando a média das latitudes e longitudes.
# Agrupar por CEP e calcular o ponto médio (média de lat/lon)
geolocation_per_zip_code <- geolocation %>%
group_by(geolocation_zip_code_prefix) %>%
arrange(geolocation_zip_code_prefix) %>%
summarise(
geolocation_lat = mean(geolocation_lat, na.rm = TRUE),
geolocation_lng = mean(geolocation_lng, na.rm = TRUE)
) %>%
ungroup()
print(head(geolocation_per_zip_code, 50))
## # A tibble: 50 × 3
## geolocation_zip_code_prefix geolocation_lat geolocation_lng
## <chr> <dbl> <dbl>
## 1 01001 -23.55019 -46.63402
## 2 01002 -23.54815 -46.63498
## 3 01003 -23.54899 -46.63573
## 4 01004 -23.54980 -46.63476
## 5 01005 -23.54946 -46.63673
## 6 01006 -23.55010 -46.63614
## 7 01007 -23.55005 -46.63725
## 8 01008 -23.54600 -46.63589
## 9 01009 -23.54684 -46.63649
## 10 01010 -23.54639 -46.63523
## # ℹ 40 more rows
Preparação de tabelas transacionais secundárias e limpeza de valores ausentes
Um pedido pode ter mais de ujm item e meio de pagamento (como descrito no proprio link da base de dados). Então é necessário agrupar.
# 1. Calcular o valor total financeiro do pedido
payments_agg_valor <- order_payments %>%
group_by(order_id) %>%
summarise(valor_total_pedido = sum(payment_value, na.rm = TRUE))
# 2. Identificar o método de pagamento principal (primeira sequencia)
payments_agg_tipo <- order_payments %>%
filter(payment_sequential == 1) %>%
select(order_id, tipo_pagamento_principal = payment_type) %>%
distinct(order_id, .keep_all = TRUE)
# 3. Junção final de pagamentos
payments_final <- payments_agg_valor %>%
left_join(payments_agg_tipo, by = "order_id")
Nem todo mundo escreve comentários em suas reviews de compra, então há muitos valores nulos nas colunas de comentários e títulos de avaliações. Além disso, alguns pedidos tem mais de um registro de comentários (clientes que mudaram de opinião).
# Tratamento de NAs e Seleção da Review mais recente
reviews_final <- order_reviews %>%
mutate(
review_comment_message = replace_na(review_comment_message, "sem_comentario"),
review_comment_title = replace_na(review_comment_title, "sem_comentario"),
review_creation_date = as_datetime(review_creation_date)
) %>%
group_by(order_id) %>%
arrange(desc(review_creation_date)) %>%
slice(1) %>% # Mantém apenas a última review
ungroup() %>%
select(order_id, review_score, review_comment_message)
Construção das três tabelas analíticas principais, integrando as tabelas limpas anteriormente.
tb_comercial <- order_items %>%
# Selecionar apenas colunas relevantes da base
select(order_id, order_item_id, product_id, seller_id, price, freight_value) %>%
# 1. Juntar com Pedidos (apenas datas essenciais e status)
left_join(orders %>% select(order_id, order_status, order_purchase_timestamp), by = "order_id") %>%
# 2. Juntar com Produtos (já traduzidos e com NAs tratados)
left_join(products, by = "product_id") %>%
# 3. Juntar com Vendedores (apenas localização básica)
left_join(sellers %>% select(seller_id, seller_city, seller_state), by = "seller_id") %>%
# 4. Juntar com Pagamentos Agregados (Valor total do pedido e forma de pagamento)
# Lembra da pré-agregação feita na Etapa 3a para evitar duplicatas
left_join(payments_final, by = "order_id")
geo_cust <- geolocation_per_zip_code %>%
select(geolocation_zip_code_prefix, lat_cli = geolocation_lat, lng_cli = geolocation_lng)
geo_sell <- geolocation_per_zip_code %>%
select(geolocation_zip_code_prefix, lat_venda = geolocation_lat, lng_venda = geolocation_lng)
# Criando a tb_logistica
tb_logistica <- order_items %>%
select(order_id, order_item_id, seller_id, freight_value) %>%
# 1. Juntar dados de Pedidos
left_join(orders, by = "order_id") %>%
# 2. Juntar CEP do Vendedor
left_join(sellers %>% select(seller_id, seller_zip_code_prefix, seller_state), by = "seller_id") %>%
# 3. Juntar CEP do Cliente
left_join(customers %>% select(customer_id, customer_zip_code_prefix, customer_state), by = "customer_id") %>%
# 4. Juntar Coordenadas (Lat/Lon)
left_join(geo_sell, by = c("seller_zip_code_prefix" = "geolocation_zip_code_prefix")) %>%
left_join(geo_cust, by = c("customer_zip_code_prefix" = "geolocation_zip_code_prefix"))
tb_clientes <- orders %>%
# 1. Trazer quem é o cliente único
left_join(customers, by = "customer_id") %>%
# 2. Trazer o valor gasto (da tabela de pagamentos pré-agregada)
left_join(payments_final, by = "order_id") %>%
# 3. Trazer nota do review
left_join(reviews_final, by = "order_id") %>%
group_by(customer_unique_id) %>%
summarise(
# Dados Cadastrais
cidade = first(customer_city),
estado = first(customer_state),
# Métricas Brutas
total_pedidos = n(),
total_gasto = sum(valor_total_pedido, na.rm = TRUE),
# Datas
data_primeira_compra = min(order_purchase_timestamp),
data_ultima_compra = max(order_purchase_timestamp),
# Satisfação Média bruta
nota_media = mean(review_score, na.rm = TRUE)
) %>%
ungroup()
tb_comercial <- tb_comercial %>%
mutate(
# Volume do produto
volume_produto_cm3 = product_length_cm * product_height_cm * product_width_cm,
)
tb_logistica <- tb_logistica %>%
mutate(
# Variáveis de Tempo
tempo_processamento_horas = as.numeric(difftime(order_approved_at, order_purchase_timestamp, units = "hours")),
tempo_entrega_total_dias = as.numeric(difftime(order_delivered_customer_date, order_purchase_timestamp, units = "days")),
atraso_entrega_dias = as.numeric(difftime(order_delivered_customer_date, order_estimated_delivery_date, units = "days")),
# Variáveis Categóricas (SLA)
status_sla = case_when(
atraso_entrega_dias > 0 ~ "Atrasado",
atraso_entrega_dias <= 0 ~ "No Prazo/Adiantado"
),
)
# Data de referência para limitar análises
data_ref <- max(orders$order_purchase_timestamp, na.rm = TRUE) + days(1)
tb_clientes <- tb_clientes %>%
mutate(
# 1. Cliente Recorrente
# Se total_pedidos > 1, é recorrente
tipo_cliente = ifelse(total_pedidos > 1, "Recorrente", "Novo"),
# 2. Recência (Dias sem comprar)
recencia_dias = as.numeric(difftime(data_ref, data_ultima_compra, units = "days")),
# 3. Ticket Médio (Valor Gasto / Qtd Pedidos)
ticket_medio = total_gasto / total_pedidos
)
tb_comercial <- tb_comercial %>%
select(
# Remove metadados de qualidade do cadastro do produto
-product_name_lenght,
-product_description_lenght,
-product_photos_qty,
# Remove dimensões individuais (já temos volume e densidade)
-product_length_cm,
-product_height_cm,
-product_width_cm
)
# Verificando o resultado
colnames(tb_comercial)
## [1] "order_id" "order_item_id"
## [3] "product_id" "seller_id"
## [5] "price" "freight_value"
## [7] "order_status" "order_purchase_timestamp"
## [9] "product_category_name" "product_weight_g"
## [11] "seller_city" "seller_state"
## [13] "valor_total_pedido" "tipo_pagamento_principal"
## [15] "volume_produto_cm3"
tb_logistica <- tb_logistica %>%
select(
# Remove datas intermediárias que já viraram métricas de tempo
-order_approved_at,
-order_delivered_carrier_date
)
# Verificando o resultado
colnames(tb_logistica)
## [1] "order_id" "order_item_id"
## [3] "seller_id" "freight_value"
## [5] "customer_id" "order_status"
## [7] "order_purchase_timestamp" "order_delivered_customer_date"
## [9] "order_estimated_delivery_date" "seller_zip_code_prefix"
## [11] "seller_state" "customer_zip_code_prefix"
## [13] "customer_state" "lat_venda"
## [15] "lng_venda" "lat_cli"
## [17] "lng_cli" "tempo_processamento_horas"
## [19] "tempo_entrega_total_dias" "atraso_entrega_dias"
## [21] "status_sla"