Generate Sample Data
# Set seed for reproducibility
set.seed(123)
# Generate sample data spanning 2011-2016
dates <- seq(as.Date("2011-01-01"), as.Date("2016-12-31"), by = "week")
n <- length(dates)
# Create weekly sales data with seasonal patterns
weekly_data <- data.frame(
Date = dates,
Sales = 300000 + 50000 * sin(2 * pi * as.numeric(dates - min(dates)) / 365.25) +
rnorm(n, 0, 30000)
)
# Create quarterly aggregated data
quarterly_data <- weekly_data %>%
mutate(Quarter = quarter(Date, with_year = TRUE)) %>%
group_by(Quarter) %>%
summarise(
Date = mean(Date),
Sales = mean(Sales),
.groups = "drop"
)
# Create monthly aggregated data
monthly_data <- weekly_data %>%
mutate(Month = floor_date(Date, "month")) %>%
group_by(Month) %>%
summarise(
Date = Month,
Sales = mean(Sales),
.groups = "drop"
)
Custom Plotting Function
# Function to create time series plot with smoothed line
create_ts_plot <- function(data, title, y_max = 800000) {
p <- ggplot(data, aes(x = Date, y = Sales)) +
geom_point(size = 1.5, alpha = 0.6) +
geom_smooth(method = "loess", se = TRUE, color = "blue",
fill = "lightblue", alpha = 0.3, span = 0.3) +
scale_y_continuous(
labels = scales::dollar_format(scale = 1e-3, suffix = "K"),
limits = c(0, y_max)
) +
scale_x_date(date_breaks = "1 year", date_labels = "%Y") +
labs(
title = title,
x = NULL,
y = "Revenue (USD)"
) +
theme_minimal() +
theme(
plot.title = element_text(hjust = 0.5, size = 12, face = "bold"),
panel.grid.major = element_line(color = "gray90"),
panel.grid.minor = element_blank(),
axis.text = element_text(size = 10),
axis.title.y = element_text(size = 10)
)
return(p)
}
Category Sales Charts
Generate Category Data
# Categories and colors
categories <- c("Cross Country Race", "Over Mountain", "Trail", "Sport", "Fat Bike")
colors <- c("darkslategray", "red", "turquoise", "tan", "lightblue")
# Function to create category-specific data
create_category_data <- function(base_sales, amplitude, dates) {
data.frame(
Date = dates,
Sales = base_sales + amplitude * sin(2 * pi * as.numeric(dates - min(dates)) / 365.25) +
rnorm(length(dates), 0, amplitude * 0.3)
)
}
# Weekly category data
weekly_cat_data <- bind_rows(
create_category_data(100000, 20000, dates) %>% mutate(Category = categories[1]),
create_category_data(80000, 15000, dates) %>% mutate(Category = categories[2]),
create_category_data(70000, 18000, dates) %>% mutate(Category = categories[3]),
create_category_data(60000, 12000, dates) %>% mutate(Category = categories[4]),
create_category_data(50000, 10000, dates) %>% mutate(Category = categories[5])
)
# Convert Category to factor with specific order
weekly_cat_data$Category <- factor(weekly_cat_data$Category, levels = categories)
Sales By Category 2 - Weekly
p_cat_weekly <- ggplot(weekly_cat_data, aes(x = Date, y = Sales, color = Category, fill = Category)) +
geom_point(size = 1, alpha = 0.5) +
geom_smooth(method = "loess", se = TRUE, alpha = 0.2, span = 0.2) +
facet_wrap(~ Category, ncol = 1, scales = "free_y", strip.position = "top") +
scale_color_manual(values = colors) +
scale_fill_manual(values = colors) +
scale_y_continuous(labels = scales::dollar_format(scale = 1e-3, suffix = "K")) +
scale_x_date(date_breaks = "2 years", date_labels = "%Y") +
labs(
title = "Sales By Category 2\nWeekly",
x = NULL,
y = NULL
) +
theme_minimal() +
theme(
plot.title = element_text(hjust = 0.5, size = 14, face = "bold"),
strip.background = element_rect(fill = "darkslategray", color = NA),
strip.text = element_text(color = "white", face = "bold", size = 10),
panel.grid.major = element_line(color = "gray90"),
panel.grid.minor = element_blank(),
legend.position = "none",
panel.spacing = unit(0.5, "lines")
)
print(p_cat_weekly)

Monthly Category Sales
# Create monthly category data
monthly_cat_data <- weekly_cat_data %>%
mutate(Month = floor_date(Date, "month")) %>%
group_by(Month, Category) %>%
summarise(
Date = Month,
Sales = mean(Sales),
.groups = "drop"
)
p_cat_monthly <- ggplot(monthly_cat_data, aes(x = Date, y = Sales, color = Category, fill = Category)) +
geom_point(size = 2, alpha = 0.6) +
geom_smooth(method = "loess", se = TRUE, alpha = 0.2, span = 0.3) +
facet_wrap(~ Category, ncol = 1, scales = "free_y", strip.position = "top") +
scale_color_manual(values = colors) +
scale_fill_manual(values = colors) +
scale_y_continuous(labels = scales::dollar_format(scale = 1e-3, suffix = "K")) +
scale_x_date(date_breaks = "2 years", date_labels = "%Y") +
labs(
title = "Sales By Category 2\nMonthly",
x = NULL,
y = NULL
) +
theme_minimal() +
theme(
plot.title = element_text(hjust = 0.5, size = 14, face = "bold"),
strip.background = element_rect(fill = "darkslategray", color = NA),
strip.text = element_text(color = "white", face = "bold", size = 10),
panel.grid.major = element_line(color = "gray90"),
panel.grid.minor = element_blank(),
legend.position = "none",
panel.spacing = unit(0.5, "lines")
)
print(p_cat_monthly)

Quarterly Category Sales
# Create quarterly category data
quarterly_cat_data <- weekly_cat_data %>%
mutate(Quarter = quarter(Date, with_year = TRUE)) %>%
group_by(Quarter, Category) %>%
summarise(
Date = mean(Date),
Sales = mean(Sales),
.groups = "drop"
)
p_cat_quarterly <- ggplot(quarterly_cat_data, aes(x = Date, y = Sales, color = Category, fill = Category)) +
geom_point(size = 3, alpha = 0.8) +
geom_smooth(method = "loess", se = FALSE, linewidth = 1.5, span = 0.5) +
facet_wrap(~ Category, ncol = 1, scales = "free_y", strip.position = "top") +
scale_color_manual(values = colors) +
scale_fill_manual(values = colors) +
scale_y_continuous(labels = scales::dollar_format(scale = 1e-3, suffix = "K")) +
scale_x_date(date_breaks = "1 year", date_labels = "%Y") +
labs(
title = "Sales By Category 2\nQuarterly",
x = NULL,
y = NULL
) +
theme_minimal() +
theme(
plot.title = element_text(hjust = 0.5, size = 14, face = "bold"),
strip.background = element_rect(fill = "darkslategray", color = NA),
strip.text = element_text(color = "white", face = "bold", size = 10),
panel.grid.major = element_line(color = "gray90"),
panel.grid.minor = element_blank(),
legend.position = "none",
panel.spacing = unit(0.5, "lines")
)
print(p_cat_quarterly)

Summary Statistics
# Create summary table
summary_table <- weekly_cat_data %>%
group_by(Category) %>%
summarise(
Mean_Sales = mean(Sales),
Median_Sales = median(Sales),
SD_Sales = sd(Sales),
Min_Sales = min(Sales),
Max_Sales = max(Sales),
.groups = "drop"
) %>%
mutate(across(where(is.numeric), ~scales::dollar(.x, accuracy = 1)))
knitr::kable(summary_table, caption = "Sales Summary by Category")
Sales Summary by Category
| Cross Country Race |
$99,976 |
$99,689 |
$15,782 |
$64,527 |
$131,228 |
| Over Mountain |
$80,277 |
$78,444 |
$11,664 |
$55,935 |
$107,074 |
| Trail |
$69,943 |
$68,879 |
$13,726 |
$40,220 |
$102,109 |
| Sport |
$60,172 |
$60,128 |
$9,245 |
$42,674 |
$83,932 |
| Fat Bike |
$50,105 |
$49,953 |
$7,477 |
$34,565 |
$64,813 |