O comércio eletrônico no Brasil tem experimentado um crescimento exponencial nas últimas décadas, impulsionado por avanços tecnológicos, maior penetração da internet e mudanças nos hábitos de consumo. Entre 2016 e 2018, período coberto por este relatório, o setor enfrentava desafios significativos relacionados à infraestrutura logística, desigualdades regionais e a necessidade de construir confiança entre consumidores e vendedores. Este relatório apresenta uma análise exaustiva e multidimensional do conjunto de dados públicos da Olist, compreendendo aproximadamente 100.000 pedidos realizados entre os anos de 2016 e 2018. Mais do que um exercício retrospectivo, esta análise serve como um estudo de caso fundamental para compreender as dores de crescimento do comércio eletrônico brasileiro, oferecendo lições valiosas que ecoam até os dias atuais em 2025, quando o mercado brasileiro projeta alcançar R$ 224,7 bilhões em receita, com 94 milhões de pessoas realizando compras online (AvenPes 2025).
A Olist, operando como um integrador de marketplaces, conecta pequenas e médias empresas (PMEs) a grandes vitrines digitais, democratizando o acesso ao e-commerce para empreendedores de todo o país. A análise de seus dados revela a saúde de uma vasta rede de varejo fragmentada, operando sob as complexas restrições geográficas e infraestruturais do Brasil. Conforme discutido em estudos sobre urbanização logística (MATOS 2024), o desafio do “last-mile” (última milha) no Brasil é exacerbado por dimensões continentais e infraestrutura desigual, fatores que são claramente visíveis neste dataset. Esses elementos não apenas destacam as barreiras enfrentadas na época, mas também contextualizam as transformações subsequentes, como a expansão de centros de distribuição no Nordeste e a adoção de tecnologias como o PIX, que revolucionaram os pagamentos digitais.
Além disso, este relatório busca conectar o passado ao presente, ilustrando como os insights derivados desses dados históricos anteciparam tendências que moldaram o e-commerce brasileiro. Por exemplo, o foco em logística eficiente e satisfação do cliente reflete as estratégias atuais de grandes players como Mercado Livre e Amazon, que investiram pesadamente em infraestrutura regional para mitigar desigualdades. Em um cenário onde o e-commerce cresceu 7% no primeiro semestre de 2025 em comparação com 2024 (E-commerce Brasil 2025), impulsionado por um mercado de trabalho forte e inflação controlada, entender esses padrões históricos é crucial para estratégias futuras.
Nosso objetivo é transformar dados transacionais brutos em inteligência competitiva acionável, alinhando-se às melhores práticas de análise de negócios:
Para desbravar esses dados, utilizaremos as seguintes bibliotecas:
tidyverse: Para manipulação ágil e
limpeza dos dados.plotly: Para criar visualizações
interativas que permitem explorar os dados em detalhes.leaflet: Para mapear geograficamente a
distribuição de vendedores e compradores.geosphere: Para calcular as distâncias
reais que as mercadorias percorrem.A metodologia seguirá um fluxo lógico: começaremos com a preparação dos dados, garantindo sua qualidade; avançaremos para a engenharia de atributos, criando novas métricas relevantes; e mergulharemos na análise exploratória, onde os insights serão revelados.
library(readr)
library(dplyr)
library(lubridate)
library(stringr)
library(stringi)
library(skimr)
library(tidyr)
library(ggplot2)
library(plotly)
library(scales)
library(leaflet)
library(geosphere)
library(knitr)Antes de qualquer análise, precisamos garantir que nossos dados sejam confiáveis. O dataset da Olist é distribuído em 9 arquivos CSV relacionais, cobrindo desde o cadastro do cliente até a avaliação final do pedido.
# Carregando datasets
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") # Removido para manter PT-BR
# Regex para estados brasileiros (Auxiliar na limpeza de dados)
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"
# Função para classificar regiões
get_region <- function(state) {
case_when(
str_to_upper(state) %in% c("SP", "RJ", "MG", "ES") ~ "Sudeste",
str_to_upper(state) %in% c("PR", "SC", "RS") ~ "Sul",
str_to_upper(state) %in% c("BA", "PE", "CE", "RN", "PB", "PI", "AL", "SE", "MA") ~ "Nordeste",
str_to_upper(state) %in% c("GO", "MT", "MS", "DF") ~ "Centro-Oeste",
str_to_upper(state) %in% c("AM", "PA", "AC", "RO", "RR", "AP", "TO") ~ "Norte",
TRUE ~ "Outros"
)
}Dados do mundo real são “sujos”. Nomes de cidades, por exemplo, frequentemente apresentam inconsistências de grafia (acentos, caixa alta/baixa) que podem distorcer análises geográficas. Implementamos uma rotina de normalização para garantir que “São Paulo” e “sao paulo” sejam tratados como a mesma entidade.
Além disso, tratamos a geolocalização. Como um mesmo CEP pode ter múltiplas coordenadas registradas, calculamos o centroide (média de latitude e longitude) para cada CEP, criando uma base sólida para nossos mapas e cálculos de distância.
Dentre outros, imputamos valores ausentes e outliers, que podem distorcer análises e levar a conclusões erradas.
# Normalização de Cidades
normalize_city <- function(cities) {
cities %>%
str_to_lower() %>%
str_remove(., paste0("\\s+", brazil_states_regex, "$")) %>% # Remove estado no fim
str_replace(., ".+@.+\\..+", NA_character_) %>% # Remove emails
str_extract(., "^[^/\\\\,]+") %>% # Pega texto antes de barras
str_remove_all(., "\\(.*?\\)") %>% # Remove parenteses
str_replace_all(., "d'|d´|d`", "d'") %>% # Padroniza d'
str_remove_all(., "[\\.'ºª´\\^~]") %>% # Remove pontuação
str_remove_all(., "^[\\.]+") %>%
str_replace_all(., "-", " ") %>%
str_squish() %>% # Remove espaços extras
str_replace(., paste0("^", brazil_states_regex, "$"), NA_character_) # Remove se for só sigla de estado
}
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))
# Tratamento de Geolocalização (Centroide por CEP)
geolocation_per_zip_code <- geolocation %>%
group_by(geolocation_zip_code_prefix) %>%
summarise(
geolocation_lat = mean(geolocation_lat, na.rm = TRUE),
geolocation_lng = mean(geolocation_lng, na.rm = TRUE)
) %>%
ungroup()
# Tratamento de Valores Ausentes e Outliers
# Imputação de dimensões pela mediana
products <- products %>%
mutate(
product_length_cm = ifelse(is.na(product_length_cm), median(product_length_cm, na.rm = TRUE), product_length_cm),
product_height_cm = ifelse(is.na(product_height_cm), median(product_height_cm, na.rm = TRUE), product_height_cm),
product_width_cm = ifelse(is.na(product_width_cm), median(product_width_cm, na.rm = TRUE), product_width_cm),
product_weight_g = ifelse(is.na(product_weight_g), median(product_weight_g, na.rm = TRUE), product_weight_g)
)
# Remoção de Outliers (Top 1% de preço e frete para evitar distorções. Evita que os famosos "bugs de promoção" apareçam na análise)
order_items <- order_items %>%
filter(price < quantile(price, 0.99, na.rm = TRUE) & freight_value < quantile(freight_value, 0.99, na.rm = TRUE))
# Formatação de Categorias (PT-BR, Escrita Normal)
products <- products %>%
mutate(
product_category_name = product_category_name %>%
str_replace_all("_", " ") %>%
str_to_title()
)Para facilitar a análise, consolidamos as informações em três tabelas temáticas:
tb_logistica: Focada em prazos,
distâncias e localização.tb_clientes: Focada no perfil de
consumo e métricas RFM(Recência, Frequência e Monetário).tb_comercial: Focada em vendas,
produtos e categorias.# Agregações prévias
payments_agg <- order_payments %>%
group_by(order_id) %>%
summarise(valor_total_pedido = sum(payment_value, na.rm = TRUE))
reviews_agg <- order_reviews %>%
arrange(desc(review_creation_date)) %>%
group_by(order_id) %>%
slice(1) %>%
ungroup() %>%
select(order_id, review_score, review_comment_message)
# Tabelas auxiliares de geo
geo_cust <- geolocation_per_zip_code %>% rename(lat_cli = geolocation_lat, lng_cli = geolocation_lng)
geo_sell <- geolocation_per_zip_code %>% rename(lat_venda = geolocation_lat, lng_venda = geolocation_lng)
# 1. Tabela Logística
tb_logistica <- order_items %>%
select(order_id, order_item_id, seller_id, freight_value, price) %>%
left_join(orders, by = "order_id") %>%
left_join(sellers %>% select(seller_id, seller_zip_code_prefix, seller_state), by = "seller_id") %>%
left_join(customers %>% select(customer_id, customer_zip_code_prefix, customer_state), by = "customer_id") %>%
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")) %>%
mutate(
distancia_km = distHaversine(matrix(c(lng_venda, lat_venda), ncol = 2),
matrix(c(lng_cli, lat_cli), ncol = 2)) / 1000,
tempo_entrega_dias = as.numeric(difftime(order_delivered_customer_date, order_purchase_timestamp, units = "days")),
atraso_dias = as.numeric(difftime(order_delivered_customer_date, order_estimated_delivery_date, units = "days")),
status_entrega = case_when(
atraso_dias > 0 ~ "Atrasado",
TRUE ~ "No Prazo"
)
) %>%
left_join(reviews_agg, by = "order_id")
# 2. Tabela Clientes (Base para RFM)
tb_clientes <- orders %>%
filter(order_status == "delivered") %>%
left_join(customers, by = "customer_id") %>%
left_join(payments_agg, by = "order_id") %>%
left_join(reviews_agg, by = "order_id") %>%
group_by(customer_unique_id) %>%
summarise(
recencia_data = max(order_purchase_timestamp),
frequencia = n_distinct(order_id),
monetario = sum(valor_total_pedido, na.rm = TRUE),
nota_media = mean(review_score, na.rm = TRUE),
estado = first(customer_state)
) %>%
ungroup()
# 3. Tabela Comercial
tb_comercial <- order_items %>%
left_join(orders %>% select(order_id, order_purchase_timestamp), by = "order_id") %>%
left_join(products, by = "product_id") %>%
mutate(mes_ano = floor_date(order_purchase_timestamp, "month"))O comércio eletrônico no Brasil não é estático; ele pulsa conforme a economia e datas comemorativas, refletindo não apenas tendências de consumo, mas também o impacto de eventos macroeconômicos e sazonais. Entender essa dinâmica é o primeiro passo para qualquer planejamento estratégico, pois permite identificar padrões de crescimento, picos de demanda e potenciais riscos operacionais. Ao analisarmos a evolução temporal das vendas no Olist, que totalizam 11.674.229 reais em receita bruta, buscamos identificar tendências de crescimento e a influência de eventos sazonais, como feriados e promoções nacionais.
O gráfico abaixo revela uma trajetória de crescimento consistente ao longo de 2017, com um aumento gradual que indica a maturação do mercado e aumento de confiança do consumidor em relação ao e-commerce. Contudo, um evento se destaca drasticamente: a Black Friday de Novembro de 2017. Esse pico não é apenas um dado estatístico; ele representa o momento de maior estresse e oportunidade para a operação, onde a capacidade logística e de atendimento é testada ao limite. Essa sazonalidade extrema destaca a importância de preparações robustas para eventos de alto volume, uma lição que ressoa em 2025, quando o e-commerce brasileiro continua a crescer, impulsionado por inovações como a IA em marketing e estratégias omnichannel.
vendas_temporal <- tb_comercial %>%
group_by(mes_ano) %>%
summarise(receita = sum(price, na.rm = TRUE)) %>%
filter(mes_ano >= "2017-01-01" & mes_ano <= "2018-08-01")
p_vendas <- ggplot(vendas_temporal, aes(x = mes_ano, y = receita)) +
geom_line(color = "#2c3e50", size = 1) +
geom_area(fill = "#3498db", alpha = 0.2) +
geom_point(color = "#c0392b", size = 2, aes(text = paste("Data:", format(mes_ano, "%b %Y"), "<br>Receita: R$", format(receita, big.mark=".", decimal.mark=",")))) +
scale_y_continuous(labels = scales::dollar_format(prefix = "R$ ", big.mark = ".", decimal.mark = ",")) +
theme_minimal() +
labs(
title = "Evolução Mensal da Receita (2017-2018)",
x = "Mês",
y = "Receita Total"
)
ggplotly(p_vendas, tooltip = "text")Essa análise temporal não apenas quantifica o crescimento, mas também oferece insights sobre a resiliência do setor. Por exemplo, o aumento pós-Black Friday sugere um efeito de retenção, onde clientes satisfeitos retornam, embora, como veremos em seções posteriores, a recorrência geral permaneça baixa devido a desafios logísticos.
No e-commerce, a venda só termina quando o produto chega nas mãos do cliente. No Brasil, isso é um grande desafio, dado o tamanho continental do país e as disparidades em infraestrutura de transporte. A logística é frequentemente citada como o principal ponto de fricção na experiência de compra, afetando não apenas a satisfação imediata, mas também a lealdade a longo prazo. Mas o quanto isso realmente impacta a percepção do cliente? Esta seção explora essa relação, conectando dados operacionais com feedback dos consumidores.
Primeiro, vamos visualizar a distribuição geográfica dos atores dessa rede. O mapa abaixo mostra a localização de 3095 vendedores (vermelho) e 99441 compradores (azul). Note a concentração massiva no Sudeste e Sul, o que já nos dá uma pista sobre os desafios de atender o restante do país. Essa desigualdade geográfica reflete problemas estruturais, como estradas precárias e custos elevados de transporte para regiões remotas, que persistem mesmo em 2025, embora mitigados por investimentos em centros de distribuição.
# Amostra para performance do mapa
map_data <- tb_logistica %>%
filter(!is.na(lat_cli) & !is.na(lat_venda)) %>%
sample_n(2000)
leaflet(map_data) %>%
addTiles() %>%
addCircleMarkers(lng = ~lng_cli, lat = ~lat_cli, radius = 2, color = "blue",
popup = "Cliente", group = "Clientes") %>%
addCircleMarkers(lng = ~lng_venda, lat = ~lat_venda, radius = 2, color = "red",
popup = "Vendedor", group = "Vendedores") %>%
addLegend("bottomright", colors = c("blue", "red"), labels = c("Clientes", "Vendedores"),
title = "Distribuição Geográfica")Agora, vamos à prova de fogo: a correlação entre tempo de entrega e a nota dada pelo cliente (Review Score). O gráfico a seguir é revelador. Existe uma relação inversa clara: clientes insatisfeitos (notas 1 e 2) são, em sua maioria, aqueles que sofreram com demoras na entrega. Enquanto avaliações de 5 estrelas estão associadas a entregas rápidas, os atrasos e longos prazos são os maiores detratores da marca. Essa descoberta reforça estudos que indicam a logística como fator chave na percepção de qualidade (MATOS 2024), e destaca a necessidade de novas estratégias.
p_review <- tb_logistica %>%
filter(!is.na(review_score) & tempo_entrega_dias > 0 & tempo_entrega_dias < 60) %>%
mutate(review_score = as.factor(review_score)) %>%
ggplot(aes(x = review_score, y = tempo_entrega_dias, fill = review_score)) +
geom_boxplot(outlier.shape = NA, alpha = 0.7) +
coord_cartesian(ylim = c(0, 40)) +
scale_fill_brewer(palette = "RdYlGn") +
theme_minimal() +
labs(
title = "Impacto do Tempo de Entrega na Avaliação do Cliente",
x = "Nota da Avaliação (Estrelas)",
y = "Tempo de Entrega (Dias)"
)
ggplotly(p_review) %>% layout(showlegend = FALSE)Em resumo, essa seção demonstra que melhorias logísticas não são apenas operacionais, mas estratégicas, impactando diretamente a satisfação e a retenção de clientes.
Por que o e-commerce ainda engatinha em regiões como o Norte e Nordeste? A resposta muitas vezes reside no custo e no prazo, que criam barreiras significativas para a inclusão digital. Para um consumidor em São Paulo, o frete é muitas vezes irrisório, facilitando compras impulsivas. Para alguém em Manaus ou Belém, o frete pode custar quase metade do valor do produto, limitando o acesso a bens essenciais e de consumo. Esta seção examina essa desigualdade estrutural, conhecida como “Custo Brasil”, e suas implicações para o mercado.
Analisamos aqui o Peso do Frete, que é a razão entre o valor do frete e o valor do produto. Os dados revelam uma desigualdade estrutural: no Norte, o frete representa cerca de 27% do valor da compra, comparado a apenas 16% no Sudeste. Embora não inviabilize totalmente, cria uma fricção considerável, corroborando análises que apontam o frete como ofensor principal na conversão.
regional_analysis <- tb_logistica %>%
mutate(regiao = get_region(customer_state)) %>%
filter(regiao != "Outros") %>%
group_by(regiao) %>%
summarise(
frete_medio = mean(freight_value, na.rm = TRUE),
preco_medio = mean(price, na.rm = TRUE),
tempo_medio = mean(tempo_entrega_dias, na.rm = TRUE),
ticket_medio = sum(price) / n_distinct(order_id),
share_pedidos = n() / nrow(tb_logistica)
) %>%
mutate(freight_burden = frete_medio / preco_medio)
p_burden <- ggplot(regional_analysis, aes(x = reorder(regiao, freight_burden), y = freight_burden, fill = regiao,
text = paste("Região:", regiao, "<br>Peso do Frete:", percent(freight_burden, 0.1)))) +
geom_col() +
scale_y_continuous(labels = scales::percent) +
theme_minimal() +
labs(
title = "O Peso do Frete: Custo de Envio vs. Valor do Produto",
x = "Região",
y = "Razão Frete / Preço (%)"
)
ggplotly(p_burden, tooltip = "text")Será que, para justificar o frete caro, os clientes do Norte e Nordeste fazem compras maiores? Analisamos o Ticket Médio (valor médio gasto por pedido) em cada região, explorando se esse comportamento é uma estratégia de otimização.
p_ticket <- ggplot(regional_analysis, aes(x = reorder(regiao, ticket_medio), y = ticket_medio, fill = regiao,
text = paste("Região:", regiao, "<br>Ticket Médio: R$", format(ticket_medio, big.mark=".", decimal.mark=",")))) +
geom_col() +
coord_flip() +
scale_y_continuous(labels = scales::dollar_format(prefix = "R$ ", big.mark = ".", decimal.mark = ",", digits = 2)) +
theme_minimal() +
labs(
title = "Ticket Médio por Região",
subtitle = "Clientes de regiões mais distantes tendem a gastar mais por pedido?",
x = "Região",
y = "Valor Médio do Pedido (R$)"
)
ggplotly(p_ticket, tooltip = "text")Insight: Observamos que o Ticket Médio no Norte e Nordeste tende a ser ligeiramente superior ou competitivo com o Sudeste. Isso sugere um comportamento de “otimização do frete”: já que o envio é caro, o consumidor prefere comprar itens de maior valor agregado ou fazer compras maiores para “diluir” esse custo fixo. Essa estratégia destaca oportunidades para programas de frete grátis acima de certos valores.
Além de pagar mais caro, o cliente dessas regiões espera muito mais. Enquanto o Sul e Sudeste recebem produtos em cerca de uma semana, o Norte espera, em média, quase um mês. Essa disparidade logística não é apenas um inconveniente; é um fator de exclusão de mercado, que tem sido abordado em anos recentes com expansões regionais.
p_time <- ggplot(regional_analysis, aes(x = reorder(regiao, tempo_medio), y = tempo_medio, fill = regiao,
text = paste("Região:", regiao, "<br>Tempo Médio:", round(tempo_medio, 1), "dias"))) +
geom_col() +
coord_flip() +
theme_minimal() +
labs(
title = "Tempo Médio de Entrega por Região",
x = "Região",
y = "Dias Corridos"
)
ggplotly(p_time, tooltip = "text")Insight Estratégico: A diferença de tempo médio de entrega entre regiões é um indicador crucial de desigualdade regional. O Norte e Nordeste, com entregas mais lentas, representam um desafio significativo para equilibrar o mercado nacional. Isso justifica investimentos regionais e políticas de logística para reduzir o tempo de espera e melhorar a experiência do cliente. Essa análise regional sublinha a necessidade de investimentos localizados para equilibrar o mercado nacional.
Ao analisarmos o ticket médio (valor do pedido) por região, deparamo-nos com um insight que desafia a intuição inicial: o ticket médio de compras nas regiões Norte e Nordeste é consistentemente superior ao do Sudeste. Esse fenômeno revela camadas profundas de desigualdade econômica no e-commerce brasileiro.
Isso não deve ser interpretado como um sinal de maior afluência nessas regiões. Pelo contrário, trata-se de um fenômeno clássico de Viés de Seleção Econômica impulsionado por barreiras logísticas. O alto custo do frete atua como um filtro rigoroso, eliminando a viabilidade de compras de baixo valor. Conforme apontado por especialistas em logística, quando o valor do frete ultrapassa uma certa porcentagem do valor do produto (frequentemente citada como 20-30%), a taxa de abandono de carrinho dispara (E-commerce Brasil 2024). Para um consumidor no Nordeste, comprar um item de R$ 30,00 pagando R$ 40,00 de frete é irracional. Portanto, essas transações simplesmente não acontecem.
O que resta são as transações de alto valor agregado (eletrônicos, móveis de design) ou compras consolidadas (“cesta cheia”), onde o consumidor dilui o custo fixo do frete em vários itens. Isso infla artificialmente o ticket médio observado, mascarando a demanda reprimida por produtos acessíveis.
A “cauda longa” do e-commerce, que permite a venda de itens nichados em volumes baixos, é inviabilizada nessas regiões devido ao frete. O gráfico abaixo ilustra esse fenômeno de forma visual. Observe como nas regiões Norte e Nordeste a base de produtos baratos (canto inferior esquerdo, onde Preço < R$ 100 e Frete < R$ 50) é muito mais escassa e dispersa do que no Sudeste, onde há uma nuvem densa de micro-transações. Essa visualização destaca como o frete atua como barreira, limitando a diversidade de compras.
p_paradox <- tb_logistica %>%
filter(price < 500 & freight_value < 100) %>% # Filtro para melhor visualização
sample_n(5000) %>% # Amostragem para performance do gráfico interativo
mutate(regiao = get_region(customer_state)) %>%
filter(regiao != "Outros") %>%
ggplot(aes(x = freight_value, y = price, color = regiao)) +
geom_point(alpha = 0.3, size = 1) +
geom_smooth(method = "lm", se = FALSE, color = "black", linetype = "dashed") +
facet_wrap(~regiao) +
theme_minimal() +
scale_color_viridis_d() +
labs(
title = "Paradoxo do Frete: Custo de Envio vs. Valor do Produto",
subtitle = "A barreira de entrada para itens baratos no Norte/Nordeste",
x = "Valor do Frete (R$)",
y = "Valor do Produto (R$)"
) +
theme(legend.position = "none")
ggplotly(p_paradox)Insight Estratégico: A “falta” de vendas de baixo valor no Norte/Nordeste não é falta de demanda, é inviabilidade econômica. Isso valida a estratégia recente (2019-2025) de grandes players como Amazon e Mercado Livre de abrir Centros de Distribuição no Nordeste para desbloquear esse mercado (Investindo por aí 2025; Tecnologística 2025). Em 2025, com o crescimento de 7% no e-commerce, essas iniciativas provaram ser cruciais para inclusão regional.
Em vez de olhar apenas para o preço, vamos entender a dinâmica de vendas das categorias mais populares. Quais produtos impulsionam o faturamento e como eles se comportam ao longo do ano? Essa análise sazonal é essencial para planejamento de estoque e marketing, revelando padrões que podem ser explorados para maximizar receitas.
Selecionamos as 5 principais categorias e traçamos sua evolução mensal, identificando picos e vales que coincidem com eventos como Dia das Mães ou Natal.
# Identificar Top 5 Categorias
top_cats <- tb_comercial %>%
count(product_category_name, sort = TRUE) %>%
slice_head(n = 5) %>%
pull(product_category_name)
# Filtrar e Agrupar
evolution_data <- tb_comercial %>%
filter(product_category_name %in% top_cats) %>%
filter(mes_ano >= "2017-01-01" & mes_ano <= "2018-08-01") %>%
group_by(mes_ano, product_category_name) %>%
summarise(receita = sum(price, na.rm = TRUE))
p_evo <- ggplot(evolution_data, aes(x = mes_ano, y = receita, color = product_category_name)) +
geom_line(size = 1) +
geom_point(size = 1.5) +
scale_y_continuous(labels = scales::dollar_format(prefix = "R$ ", big.mark = ".", decimal.mark = ",")) +
theme_minimal() +
labs(
title = "Evolução de Receita das Top 5 Categorias",
subtitle = "Sazonalidade e tendências de crescimento por categoria",
x = "Mês",
y = "Receita Mensal",
color = "Categoria"
)
ggplotly(p_evo)Análise: O gráfico revela padrões interessantes. Categorias como “Beleza e Saúde” mostram uma consistência impressionante, enquanto outras podem ter picos associados a datas específicas. A Black Friday de 2017 impulsionou quase todas as categorias, mas algumas sustentaram o crescimento melhor em 2018. Essa visão ajuda a prever demandas futuras, alinhando-se com tendências atuais como personalização via IA.
Em um mercado competitivo, reter um cliente é muito mais barato do que adquirir um novo. Mas nem todos os clientes são iguais. Para entender quem realmente importa, aplicamos a análise RFM (Recência, Frequência, Monetário), uma metodologia clássica que segmenta a base com base no comportamento de compra.
Identificamos grupos estratégicos:
É neste grupo de “Gastadores Únicos” que reside a maior oportunidade de receita perdida, sugerindo campanhas targeted para reengajamento.
# Data de referência: 1 dia após a última compra do dataset
data_ref <- max(tb_clientes$recencia_data) + days(1)
rfm_data <- tb_clientes %>%
mutate(
recencia_dias = as.numeric(difftime(data_ref, recencia_data, units = "days")),
# Score de Recência (5 = mais recente)
R_Score = ntile(desc(recencia_dias), 5),
# Score Monetário (5 = gasta mais)
M_Score = ntile(monetario, 5)
) %>%
mutate(
RFM_Segment = case_when(
R_Score >= 4 & M_Score >= 4 ~ "Alta Recência e Valor",
R_Score >= 3 & M_Score >= 3 ~ "Clientes Recorrentes",
R_Score <= 2 & M_Score >= 4 ~ "Alto Valor Inativo", # Gastaram muito mas faz tempo
R_Score <= 2 & M_Score <= 2 ~ "Baixo Valor / Inativo",
TRUE ~ "Novos Clientes"
)
)
# Visualização dos Segmentos
rfm_summary <- rfm_data %>%
count(RFM_Segment) %>%
mutate(prop = n / sum(n))
p_rfm <- ggplot(rfm_summary, aes(x = reorder(RFM_Segment, prop), y = prop, fill = RFM_Segment,
text = paste("Segmento:", RFM_Segment, "<br>Share:", percent(prop, 0.1)))) +
geom_col() +
coord_flip() +
scale_y_continuous(labels = scales::percent) +
theme_minimal() +
labs(
title = "Segmentação de Clientes (Matriz RM)",
x = "Segmento",
y = "Proporção da Base"
) +
theme(legend.position = "none")
ggplotly(p_rfm, tooltip = "text")Insight Estratégico: A segmentação RFM revela um cenário desafiador: apenas 20% dos clientes são recorrentes. Isso é característico de um modelo de marketplace puro sem programas de fidelidade fortes na época. Essa baixa recorrência destaca a importância de estratégias de retenção, como e-mails personalizados ou incentivos.
Por fim, olhamos para o portfólio. Quais categorias sustentam o faturamento? Essa análise de Curva ABC ajuda a priorizar esforços em produtos de alto impacto.
O gráfico abaixo mostra as top 15 categorias por receita. Vemos uma disputa acirrada no topo, com “Beleza Saude” liderando com pouco mais de R$ 1 milhão em vendas, seguida de perto por “Cama Mesa Banho” e “Relogios Presentes”. Essas categorias “Core” são o motor do marketplace, sugerindo foco em promoções e estoque para elas.
pareto_cat <- tb_comercial %>%
group_by(product_category_name) %>%
summarise(receita = sum(price, na.rm = TRUE)) %>%
arrange(desc(receita)) %>%
mutate(
acumulado = cumsum(receita),
prop_acumulada = acumulado / sum(receita) * 100
) %>%
slice_head(n = 15)
p_pareto <- ggplot(pareto_cat, aes(x = reorder(product_category_name, receita))) +
geom_col(aes(y = receita, text = paste("Categoria:", product_category_name, "<br>Receita: R$", format(receita, big.mark=".", decimal.mark=","))), fill = "#2c3e50") +
coord_flip() +
scale_y_continuous(labels = scales::dollar_format(prefix = "R$ ", big.mark = ".", decimal.mark = ",")) +
theme_minimal() +
labs(
title = "Top 15 Categorias por Receita",
x = "Categoria",
y = "Receita Total"
)
ggplotly(p_pareto, tooltip = "text")Insight Estratégico: Essa distribuição reforça a necessidade de diversificação, mas com ênfase nas categorias líderes para maximizar rentabilidade.
Esta análise dos dados de 2016-2018 serve como um “raio-x” das dores que moldaram a revolução logística brasileira na década seguinte. A Olist, como microcosmo do e-commerce nacional, evidenciou gargalos que exigiram investimentos massivos em infraestrutura, culminando no robusto crescimento observado em 2025. Com o setor projetado para atingir US$ 36,3 bilhões em receita e 94 milhões de usuários online, os insights históricos aqui apresentados validam as estratégias adotadas, como a expansão de centros de distribuição e a integração de tecnologias avançadas.
A Logística é o Produto: A correlação entre atrasos e notas baixas é absoluta. O cliente não separa a “loja” da “transportadora”. A experiência é única. Estudos indicam que a logística é responsável por grande parte da percepção de qualidade. Em 2025, com o PIX superando cartões de crédito em pagamentos online e melhorias em last-mile delivery, esses desafios foram mitigados, mas as lições permanecem relevantes para otimização contínua.
O Nordeste é um Gigante Reprimido: O “Paradoxo do Frete” provou que o consumo no Nordeste era artificialmente limitado a itens caros e de “cesta cheia” para compensar o frete.
O Custo do Churn: A falta de retenção, muitas vezes causada por uma primeira experiência logística ruim, drena a rentabilidade. Modelos preditivos de churn (Matuszelański and Kopczewska 2024) sugerem que a primeira experiência é determinante. Hoje, com IA facilitando journeys zero-click e hyper-personalização, estratégias de retenção evoluíram, mas o foco na experiência inicial permanece crucial.
Além disso, as tendências de 2025 ecoam os insights deste relatório. A integração de dados unificados, omnichannel e IA responsável permite experiências personalizadas, reduzindo churn e otimizando logística. No entanto, desafios persistem, como impostos e cybersecurity, exigindo vigilância contínua.
Recomendações Estratégicas (Baseadas nos Dados):
Em conclusão, este relatório não apenas diagnostica o passado, mas ilumina o futuro, enfatizando que a eficiência no e-commerce brasileiro depende de uma integração harmoniosa entre logística, dados e inovação tecnológica.