This project analyzes coffee shop sales data obtained from Kaggle. The objective is to explore sales performance, customer demand patterns, payment preferences, and peak operational periods using exploratory data analysis (EDA). The analysis aims to generate actionable insights to support business decision-making in areas such as staffing, product optimization, and revenue planning.
The data set used in this analysis consists of a merged CSV file sourced from Kaggle. It contains 3,898 coffee sales transactions recorded between March 2024 and early 2025. The data includes variables such as transaction date and time, payment method (cash or card), card information, coffee name, and revenue (money). Transaction revenue values range from approximately 15 to 40 monetary units, with an average transaction value of about 31.38. Transaction times range from 06:00 to 23:00 hours.
Data Source : Kaggle
Name : Coffee Shop Sales
Author : Yaroslav Isaienkov
Date : March, 2024.
The data set was prepared for analysis by ensuring consistent variable formats and combining the available records.
colSums(is.na(coffee_sales))
## date datetime cash_type card money coffee_name
## 0 0 0 262 0 0
## hour day month weekday
## 0 0 0 0
A total of 262 missing values were identified in the card column of coffee_sales_two. The main data set does not contain missing values, these missing values are not expected to significantly affect the analysis as the value is not used for subsequent computation. Additionally, product name was standardized by converting all entries to lowercase in other to fix redundancy.
This histogram illustrates the distribution properties of total revenue metrics recorded across the data-set. The x-axis measures total revenue in thousands, tracking values that scale from approximately 15 thousand to slightly above 40 thousand. The y-axis monitors the frequency of these transactions, showing individual interval counts that reach a maximum peak of approximately 850 transactions. This chart serves to define the baseline scale, continuous ranges, and mathematical spread of the revenue data prior to exploratory analysis.
The visualization provides a descriptive overview of the categorical distribution across the two primary payment methods recorded in the data-set. The primary metric tracked is the absolute frequency count of transactions per payment type, contrasting the categories of “card” and “cash” with total volumes reaching up to a maximum threshold of over 3000 observations. This baseline chart maps the structural dimensions and volume metrics of the payment method variable, establishing a foundation for subsequent exploratory analysis.
The visualization provides a descriptive overview of the categorical distribution across the 18 unique beverage categories present in the data-set. The primary metric tracked is the absolute frequency count of transactions recorded per product type, with individual category counts spanning from zero observations to a maximum of approximately 900 records. This baseline plot maps out the complete categorical variety of the product variable, establishing the basic structural dimensions of the sample before conducting exploratory time-based analysis.
The monthly transaction trend shows variation in the number of transactions across months. Some months exhibit higher transaction volumes, indicating periods of increased customer activity, while others show relatively lower activity levels and reaches a peak around February.
Customer demand increases during the morning hours and reaches a peak at approximately 10:00. followed by gradual decline with minor fluctuations.
A small number of products (Latte, Americano, Cappuccino, cortado, cocoa, hot chocolate) dominate demand, with Americano with milk recording the highest sales, while most other products display moderate to low or irregular sales patterns.
Card payments account for the majority of transactions, while cash payments represent a relatively small proportion.
Daily revenue fluctuates between approximately 2412.90 and 5096.58. Stronger performance is observed in early and mid-month periods, with a decline toward end of the month.
Sales are highest at the beginning of the week, particularly Mondays and Tuesdays, decline midweek particularly on Wednesdays and Thursdays with an increase on Fridays, before dropping during weekends.
The monthly revenue trend shows fluctuations in total revenue across the observed period. February records noticeably higher revenue, while March and October also show relatively high values, indicating periods of increased customer spending and stronger business performance. In contrast, the remaining months generally exhibit lower and more fluctuating revenue, suggesting an uneven distribution of sales over time.
The scatter plot shows a very strong positive linear relationship between transactions and revenue, indicating that revenue is largely driven by transaction volume, with observations closely clustered around the regression line. Only minor deviations are observed, indicating slight variations in spending per transaction.
The analysis reveals the following key insights: Sales performance is stronger on weekdays compared to weekends. Peak demand occurs at exact 10:00 in the morning, Card payments dominate customer transactions. A small subset of products account for the majority of demand, sales show predictable daily and weekly patterns.
The coffee shop exhibits clear and consistent sales patterns, with peak activity occurring in the morning hours and stronger performance during weekdays. These findings can support decisions related to staffing schedules, inventory management, and product strategy.
R Code for Data Cleaning and Analysis
library(“plotly”) library(tidyverse) library(ggplot2) library(corrplot) library(gridExtra) library(dplyr) library(stringr) library(scales) library(lubridate) coffee_sales_one <-read.csv(“C:/Users/respe/Downloads/archive/index_1.csv”) coffee_sales_two <-read.csv(“C:/Users/respe/Downloads/archive/index_2.csv”) summary(coffee_sales_one) summary(coffee_sales_two) colnames(coffee_sales_one) colnames(coffee_sales_two) head(coffee_sales_one, 10) head(coffee_sales_two, 10) tail(coffee_sales_one, 10) tail(coffee_sales_two, 10) str(coffee_sales_one) str(coffee_sales_two)
sum(sapply(coffee_sales_one, function(x) sum(is.na(x)))) sum(sapply(coffee_sales_two, function(x) sum(is.na(x))))
coffee_sales_two$card <- NA
coffee_sales <- rbind(coffee_sales_one, coffee_sales_two)
nrow(coffee_sales) head(coffee_sales) tail(coffee_sales) summary(coffee_sales)
coffee_sales\(datetime <- as.POSIXct( coffee_sales\)datetime, format = “%Y-%m-%d %H:%M:%OS” )
coffee_sales\(hour <- as.numeric(format(coffee_sales\)datetime, “%H”))
coffee_sales\(day <- as.numeric(format(coffee_sales\)datetime, “%d”))
coffee_sales\(month <- floor_date(coffee_sales\)datetime, “month”)
coffee_sales\(weekday <- factor( format(coffee_sales\)datetime, “%A”), levels = c(“Monday”,“Tuesday”,“Wednesday”, “Thursday”,“Friday”,“Saturday”,“Sunday”) )
str(coffee_sales) colSums(is.na(coffee_sales)) head(coffee_sales\(weekday) head(coffee_sales\)day) head(coffee_sales$month)
coffee_sales\(coffee_name <- trimws(tolower(coffee_sales\)coffee_name))
hourly_demand <- coffee_sales %>% count(hour, name = “demand”)
hourly_product_demand <- coffee_sales %>% count(hour, coffee_name, name = “product_demand”)
daily_sales <- coffee_sales %>% group_by(day) %>% summarise(money = sum(money, na.rm = TRUE)) %>% arrange(day)
weekly_sales <- coffee_sales %>% group_by(weekday) %>% summarise(money = sum(money, na.rm = TRUE))
monthly_data <- coffee_sales %>% mutate(month = floor_date(datetime, “month”)) %>% group_by(month) %>% summarise( revenue = sum(money, na.rm = TRUE), transactions = n() )
sum(coffee_sales\(money, na.rm = TRUE) sum(monthly_data\)revenue) sum(weekly_sales\(money) sum(daily_sales\)money)
mean(coffee_sales$money, na.rm = TRUE)
range(daily_sales$money)
str(monthly_data) ```