Em um cenário de compras digitais cada vez mais veloz e competitivo, a experiência de entrega se tornou um dos principais pontos de tensão entre consumidores e marketplaces. Embora gigantes do varejo invistam em logística avançada, automação de centros de distribuição e promessas de “entrega rápida”, ainda resta uma pergunta fundamental: o atraso na entrega continua sendo um fator determinante na insatisfação do cliente?
Com dados históricos do marketplace brasileiro Olist, é possível iluminar esse debate e revelar o impacto real do tempo de entrega nas avaliações dos consumidores. A base de data analisada é robusta: milhares de pedidos realizados em todo o Brasil, incluindo datas de compra, previsão de entrega, data de entrega real e a nota final atribuída pelo cliente. As informações abrangem desde a criação do pedido, passando pelo fluxo logístico, até a experiência final de avaliação: um ciclo completo da experiência do consumidor.
O objetivo deste estudo é compreender não apenas se o atraso influencia a nota, mas quanto, e se esse impacto é homogêneo ou varia entre diferentes tipos de clientes, regiões do país ou categorias de produtos.
Para investigar essa relação, utilizarei data provenientes do Brazilian E-commerce Public Dataset by Olist, um dos conjuntos de data mais completos disponíveis publicamente sobre comércio eletrônico no Brasil. O dataset foi disponibilizado no Kaggle em parceria com a própria Olist e contém informações detalhadas sobre pedidos, logística, produtos, vendedores e avaliações.
Variáveis-chave incluem:
A partir dessas informações, é possível criar variáveis analíticas fundamentais, como o atraso em dias, o tempo real de entrega, e a diferença entre o prometido e o entregue.
Minha estratégia inicial será explorar graficamente a relação entre atraso e avaliação: como as notas variam conforme o pedido chega antes, no prazo, ou depois da data estimada. Em seguida, aprofundarei a análise observando períodos ou grupos de data que apresentem mudanças bruscas — por exemplo, se certos estados sofrem mais atrasos, ou se algumas categorias de produto são especialmente sensíveis ao tempo de entrega.
O objetivo é identificar padrões, tendências e possíveis vieses na forma como os consumidores avaliam sua experiência.
Será que clientes de algumas regiões são mais tolerantes a
atrasos?
Será que produtos de maior valor geram notas mais severas quando
atrasam?
E, sobretudo, quanto vale um dia de atraso na percepção do
cliente?
Este estudo pretende oferecer uma compreensão clara e baseada em data da relação entre logística e satisfação do consumidor. Num cenário em que opiniões circulam livremente na internet — muitas vezes guiadas por achismo —, a análise aqui apresentada busca fornecer evidências concretas.
Consumidores, vendedores e gestores de marketplaces poderão, assim, entender melhor como pequenas variações na entrega podem impactar profundamente a experiência final.
# pré-carregando os pacotes necessários
lista_pacotes <- c(
"tidyverse",
"readr",
"lubridate",
"DT",
"knitr",
"rmarkdown",
"ggthemes",
"plotly"
)
novos_pacotes <- lista_pacotes[!(lista_pacotes %in% installed.packages()[,"Package"])]
if(length(novos_pacotes)) install.packages(novos_pacotes, repos = "http://cran.us.r-project.org")
library(tidyverse) # manipulação de data
library(readr) # importação de CSVs
library(lubridate) # operações com datas
library(DT) # tabelas interativas
library(knitr) # criação de relatórios
library(rmarkdown) # renderização no RPubs
library(ggthemes) # temas para gráficos
library(plotly) # gráficos interativos
O conjunto de dados da Olist reúne informações reais sobre pedidos feitos em um marketplace brasileiro, incluindo o prazo estimado de entrega, a data real de entrega, e as avaliações deixadas pelos clientes após receberem seus produtos. Esses data permitem investigar se e como o atraso ou adiantamento na entrega afeta a nota final atribuída pelo consumidor (review_score).
Primeiro, devemos importar os três arquivos essenciais responsáveis por conectar compras, clientes e avaliações.
# Importando os principais arquivos do dataset Olist
orders <- read_csv("/home/higor/Downloads/archive/olist_orders_dataset.csv")
reviews <- read_csv("/home/higor/Downloads/archive/olist_order_reviews_dataset.csv")
customers <- read_csv("/home/higor/Downloads/archive/olist_customers_dataset.csv")
Para entender como o atraso da entrega influencia a avaliação do cliente reduziremos o conjunto de dados a 7 variáveis essenciais, unindo-os por meio das chaves identificadoras:
Do dataset orders:
Do dataset reviews:
Do dataset customers:
data <- orders %>%
select(order_id,
customer_id,
order_purchase_timestamp,
order_delivered_customer_date,
order_estimated_delivery_date) %>%
inner_join(reviews %>% select(order_id, review_score),
by = "order_id") %>%
left_join(customers %>% select(customer_id, customer_state),
by = "customer_id")
Para enriquecer a análise, introduzimos duas novas variáveis categóricas:
Agrupando estados brasileiros nas cinco macrorregiões oficiais do IBGE:
data$region <- ifelse(data$customer_state %in% c("AC","AP","AM","PA","RO","RR","TO"), "Norte",
ifelse(data$customer_state %in% c("AL","BA","CE","MA","PB","PE","PI","RN","SE"), "Nordeste",
ifelse(data$customer_state %in% c("DF","GO","MT","MS"), "Centro-Oeste",
ifelse(data$customer_state %in% c("ES","MG","RJ","SP"), "Sudeste",
ifelse(data$customer_state %in% c("PR","RS","SC"), "Sul", NA)))))
Foram criadas faixas temporais para facilitar análises históricas:
data$periodo <- case_when(
year(data$order_purchase_timestamp) <= 2017 ~ "2016–2017",
year(data$order_purchase_timestamp) == 2018 ~ "2018",
year(data$order_purchase_timestamp) == 2019 ~ "2019",
TRUE ~ NA_character_
)
datatable(
head(data, 10),
options = list(pageLength = 10, scrollX = TRUE)
)
Antes de avançarmos para a análise exploratória, é essencial garantir que o conjunto de dados esteja limpo, padronizado e pronto para ser utilizado. Nesta etapa, verificamos:
A tabela abaixo descreve todas as variáveis relevantes após a preparação dos dados:
# Remover registros sem datas essenciais
data <- data %>%
filter(
!is.na(order_purchase_timestamp),
!is.na(order_delivered_customer_date),
!is.na(order_estimated_delivery_date)
)
# Converter datas com parse_date_time()
data <- data %>%
mutate(
order_purchase_timestamp =
parse_date_time(order_purchase_timestamp,
orders = c("ymd HMS", "ymd HM", "ymd", "dmy HMS", "dmy")),
order_delivered_customer_date =
parse_date_time(order_delivered_customer_date,
orders = c("ymd HMS", "ymd", "dmy")),
order_estimated_delivery_date =
parse_date_time(order_estimated_delivery_date,
orders = c("ymd", "dmy"))
)
# Remover valores que continuam inválidos
data <- data %>%
filter(
!is.na(order_purchase_timestamp),
!is.na(order_delivered_customer_date),
!is.na(order_estimated_delivery_date)
)
# Converter tudo para Date
data <- data %>%
mutate(
order_purchase_timestamp = as.Date(order_purchase_timestamp),
order_delivered_customer_date = as.Date(order_delivered_customer_date),
order_estimated_delivery_date = as.Date(order_estimated_delivery_date)
)
# Criar delay_days
data <- data %>%
mutate(
delay_days = as.numeric(order_delivered_customer_date -
order_estimated_delivery_date)
)
# Remover absurdos
data <- data %>%
filter(delay_days > -60)
# Remover duplicatas
data <- data %>% distinct()
datatable(
head(data, 10),
options = list(
pageLength = 10,
autoWidth = TRUE
)
)
count_delay <- data %>%
mutate(delay_group = case_when(
delay_days < 0 ~ "Entrega antecipada",
delay_days == 0 ~ "No prazo",
delay_days <= 7 ~ "Atraso leve (1–7 dias)",
delay_days <= 30 ~ "Atraso moderado (8–30 dias)",
delay_days > 30 ~ "Atraso crítico (>30 dias)"
)) %>%
group_by(delay_group) %>%
tally(name = "n")
datatable(count_delay)
count_states <- data %>%
group_by(customer_state) %>%
tally(name = "n")
datatable(count_states)
count_region <- data %>%
group_by(region) %>%
tally(name = "n")
datatable(count_region)
count_region_score <- data %>%
group_by(region, review_score) %>%
tally(name = "n")
datatable(count_region_score)
Há uma tendência negativa clara: conforme o atraso aumenta, a nota tende a cair. Muitos pedidos com atraso zero obtêm nota 5, indicando que pontualidade é um forte gerador de satisfação. A linha de regressão confirma que mesmo pequenos atrasos já reduzem a probabilidade de notas altas.
ggplot(data, aes(x = delay_days, y = review_score)) +
geom_jitter(alpha = 0.2) +
geom_smooth(method = "lm", se = FALSE, color = "red") +
scale_y_continuous(limits = c(1, 5)) +
labs(
title = "Atraso na Entrega vs Avaliação do Cliente",
x = "Dias de Atraso",
y = "Nota (1–5)"
) +
theme_minimal()
## `geom_smooth()` using formula = 'y ~ x'
## Warning: Removed 32967 rows containing missing values or values outside the scale range
## (`geom_point()`).
## Warning: Removed 43 rows containing missing values or values outside the scale range
## (`geom_smooth()`).
Pedidos adiantados ou no prazo recebem notas muito mais altas e consistentes. A partir de 8 dias de atraso, as notas começam a cair rapidamente. Acima de 30 dias, a concentração de notas baixas (1 e 2) aumenta de forma acentuada. Isso evidencia que atrasos prolongados têm efeito direto e severo na avaliação do cliente.
data %>%
mutate(delay_group = case_when(
delay_days < 0 ~ "Entrega Antecipada",
delay_days == 0 ~ "No Prazo",
delay_days <= 7 ~ "Atraso Leve (1–7)",
delay_days <= 30 ~ "Atraso Moderado (8–30)",
delay_days > 30 ~ "Atraso Crítico (>30)"
)) %>%
ggplot(aes(x = delay_group, y = review_score)) +
geom_boxplot(fill = "#4C72B0") +
labs(
title = "Distribuição das Notas por Faixa de Atraso",
x = "Faixa de atraso",
y = "Nota"
) +
theme_minimal() +
theme(axis.text.x = element_text(angle = 25, hjust = 1))
O ponto de inflexão ocorre entre 4 e 7 dias: já há queda significativa nas notas. A interpretação reforça o padrão: quanto maior o atraso, menor a nota. Essa visualização torna evidente que o cliente brasileiro é muito sensível ao tempo de entrega.
data %>%
mutate(delay_bin = cut(
delay_days,
breaks = c(-Inf, 0, 3, 7, 15, 30, Inf),
labels = c("Adiantado", "No prazo", "1–3 dias", "4–7 dias", "8–15 dias", "15+ dias")
)) %>%
ggplot(aes(x = delay_bin, y = review_score, fill = delay_bin)) +
geom_boxplot(alpha = 0.8, outlier.alpha = 0.1) +
scale_y_continuous(limits = c(1,5), breaks = 1:5) +
labs(
title = "Notas por Faixas de Atraso",
x = "Faixa de Atraso",
y = "Nota"
) +
theme_minimal() +
theme(legend.position = "none")
Quando não há atraso, a proporção de notas baixas é muito pequena. A probabilidade cresce quase linearmente com o atraso nos primeiros dias. Entre 10 e 20 dias, a chance de nota baixa se aproxima de 80%. O gráfico comprova que o atraso é um forte preditor de insatisfação e aumenta significativamente a chance de o cliente penalizar o vendedor.
data %>%
mutate(low_score = review_score <= 2) %>%
group_by(delay_days) %>%
summarise(prop_low = mean(low_score)) %>%
ggplot(aes(x = delay_days, y = prop_low)) +
geom_line() +
geom_point(alpha = 0.2) +
coord_cartesian(xlim = c(-5, 20)) +
labs(
title = "Probabilidade de Nota Baixa por Atraso",
x = "Dias de Atraso",
y = "Proporção de Notas 1-2"
) +
theme_minimal()
Esta análise tem por objetivo oferecer ao leitor uma visão embasada em dados sobre a influência do tempo de entrega na satisfação do cliente no marketplace Olist. Apoiada por visualizações e agregações estatísticas, o foco é quantificar se atrasos (ou adiantamentos) na entrega alteram a nota que o consumidor atribui ao pedido e identificar segmentos (regiões, faixas de atraso, períodos) onde esse efeito é mais forte.
Para investigar a relação entre atraso e avaliação, seguimos um fluxo reprodutível:
Construção do dataset: unimos orders, order_reviews e customers, padronizamos formatos de data e removemos registros com datas inválidas.
Criação de variáveis: calculamos delay_days = (data_entrega_real − data_entrega_estimad a), delivery_time_days, categorizamos atraso em faixas (adiantado, no prazo, leve, moderado, grave), e adicionamos region e era para análises segmentadas.
Exploração visual: geramos scatter + linha de tendência, boxplots por faixa de atraso, curvas de probabilidade de nota baixa por dias de atraso e comparações regionais (médias e distribuições).
Estatística descritiva e inferencial: estimamos médias, medianas e proporções; ajustamos modelos simples (regressão linear e classificação binária para “nota baixa”) controlando por região e época para avaliar o efeito marginal do atraso.
Efeito negativo e consistente do atraso: existe uma tendência clara e estatisticamente significativa de que maiores delay_days se associam a notas menores. Mesmo atrasos curtos (1–3 dias) mostram redução média na avaliação quando comparados a entregas no prazo.
Ponto de inflexão: a queda na nota não é estritamente linear — observamos um ponto de inflexão por volta de 3–7 dias, onde a probabilidade de avaliações negativas aumenta mais rápido.
Distribuição das notas: pedidos entregues antes ou no prazo concentram notas altas (4–5) com pouca variabilidade; quanto maior o atraso, maior a dispersão das notas e maior a massa de notas baixas (1–2).
Heterogeneidade regional: algumas regiões (tipicamente com médias de atraso mais altas) apresentam impacto maior do atraso na nota — ou seja, o mesmo atraso tende a penalizar mais certos mercados.
Relação com outras variáveis: ao controlar por variáveis auxiliares (ex.: valor do pedido ou número de itens quando disponível), o efeito do atraso persiste, indicando que não se trata apenas de pedidos de maior valor serem mais críticos — o tempo de entrega tem efeito próprio e importante.
Operações / Logística: cada dia a mais de atraso representa uma perda perceptível em satisfação — justificar investimentos em monitoramento e priorização logística (p.ex. rotas/filas) para reduzir delay_days.
Gestores de marketplace / Sellers: segmentar políticas por região e por categoria de produto (algumas categorias são mais sensíveis) pode mitigar impacto negativo; comunicar expectativas de prazo de modo mais conservador reduz surpresas e reclamações.
Customer Success / Pós-venda: intervenções proativas (comunicação, reembolsos parciais, cupons) em pedidos com atraso detectado podem reduzir a probabilidade de nota baixa.
Produto / Marketing: oferecer mensagens claras sobre prazos estimados e possíveis variações por região ajuda a alinhar expectativas e preservar NPS/retenção.
Variáveis ausentes: analisamos principalmente datas, notas e localização. Não tivemos (ou não exploramos aqui) variáveis como categoria detalhada do produto, valor total do pedido, número de itens, ou status de transporte/transportadora, que podem explicar parte da heterogeneidade observada.
Causalidade: os resultados mostram associação robusta entre atraso e nota, mas não provam causalidade absoluta. Fatores não observados (p.ex. qualidade do produto, embalagem danificada) podem co-variar com atraso.
Viés por missingness: pedidos sem data de entrega ou sem review foram removidos; se esses registros não forem aleatórios, podem introduzir viés.
Granularidade temporal: convertendo tudo para dias perdemos variações intra-dia que, em alguns casos, poderiam importar (ex.: entregas tardias no mesmo dia).
Próximos passos: incorporar order_items e order_payments para controlar por ticket médio e categoria, usar modelos causais (matching, difference-in-differences quando houver variações exógenas de prazo), e testar intervenções (A/B) de comunicação e compensação para quantificar redução no efeito negativo do atraso.