install.packages(c("gtrendsR", "tidyverse", "ggplot2", "scales",
"lubridate", "knitr", "kableExtra"))
library(gtrendsR)
library(tidyverse)
library(ggplot2)
library(scales)
library(lubridate)
library(knitr)
library(kableExtra)
This report uses Google Trends data to compare U.S. web search interest for three competing athleisure brands: Lululemon, Gymshark, and Fabletics. All three are direct-to-consumer (DTC) brands competing in the activewear and athleisure space, making them a meaningful set for comparative analysis. Five years of monthly search data are used to identify trends, seasonal patterns, and peak interest periods.
trends_raw <- gtrends(
keyword = c("Lululemon", "Gymshark", "Fabletics"),
geo = "US",
time = "today+5-y"
)
# Extract interest over time
iot <- trends_raw$interest_over_time %>%
mutate(
hits = as.numeric(ifelse(hits == "<1", "0", hits)),
date = as.Date(date)
)
glimpse(iot)
## Rows: 786
## Columns: 7
## $ date <date> 2021-06-27, 2021-07-04, 2021-07-11, 2021-07-18, 2021-07-25, …
## $ hits <dbl> 21, 19, 19, 20, 21, 20, 20, 20, 19, 17, 20, 20, 21, 20, 21, 2…
## $ keyword <chr> "Lululemon", "Lululemon", "Lululemon", "Lululemon", "Lululemo…
## $ geo <chr> "US", "US", "US", "US", "US", "US", "US", "US", "US", "US", "…
## $ time <chr> "today+5-y", "today+5-y", "today+5-y", "today+5-y", "today+5-…
## $ gprop <chr> "web", "web", "web", "web", "web", "web", "web", "web", "web"…
## $ category <int> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0…
brand_colors <- c(
"Lululemon" = "#9B1B30",
"Gymshark" = "#000000",
"Fabletics" = "#4B0082"
)
ggplot(iot, aes(x = date, y = hits, color = keyword)) +
geom_line(linewidth = 0.8, alpha = 0.7) +
geom_smooth(method = "loess", se = FALSE, linewidth = 1.2) +
scale_color_manual(values = brand_colors) +
scale_x_date(date_labels = "%b %Y", date_breaks = "6 months") +
scale_y_continuous(limits = c(0, 100)) +
labs(
title = "Google Search Interest: Lululemon vs. Gymshark vs. Fabletics",
subtitle = "United States | Past 5 Years | Web Search",
x = NULL,
y = "Relative Search Interest (0–100)",
color = "Brand",
caption = "Source: Google Trends via gtrendsR"
) +
theme_minimal(base_size = 12) +
theme(
plot.title = element_text(face = "bold", size = 14),
plot.subtitle = element_text(color = "gray50"),
axis.text.x = element_text(angle = 30, hjust = 1),
legend.position = "top"
)
iot %>%
group_by(keyword) %>%
summarise(
Mean_Interest = round(mean(hits, na.rm = TRUE), 1),
Max_Interest = max(hits, na.rm = TRUE),
Min_Interest = min(hits, na.rm = TRUE),
.groups = "drop"
) %>%
arrange(desc(Mean_Interest)) %>%
rename(Brand = keyword) %>%
kable(caption = "Search Interest Summary by Brand (Past 5 Years)") %>%
kable_styling(bootstrap_options = c("striped", "hover"),
full_width = FALSE)
| Brand | Mean_Interest | Max_Interest | Min_Interest |
|---|---|---|---|
| Lululemon | 38.2 | 100 | 17 |
| Fabletics | 4.4 | 9 | 2 |
| Gymshark | 3.5 | 11 | 2 |
iot %>%
group_by(keyword) %>%
slice_max(hits, n = 1, with_ties = FALSE) %>%
select(Brand = keyword, Peak_Date = date, Peak_Interest = hits) %>%
arrange(desc(Peak_Interest)) %>%
kable(caption = "Highest Search Interest Peak by Brand") %>%
kable_styling(bootstrap_options = c("striped", "hover"),
full_width = FALSE)
| Brand | Peak_Date | Peak_Interest |
|---|---|---|
| Lululemon | 2025-11-23 | 100 |
| Gymshark | 2021-11-14 | 11 |
| Fabletics | 2023-11-19 | 9 |
# Find peak row for each brand
peaks <- iot %>%
group_by(keyword) %>%
slice_max(hits, n = 1, with_ties = FALSE)
ggplot(iot, aes(x = date, y = hits, color = keyword)) +
geom_line(linewidth = 0.8, alpha = 0.6) +
geom_point(data = peaks, aes(x = date, y = hits),
size = 4, shape = 21, fill = "white", stroke = 1.5) +
geom_label(data = peaks,
aes(label = paste0(keyword, "\n", format(date, "%b %Y"),
"\n(", hits, ")")),
size = 3, nudge_y = 5, show.legend = FALSE) +
scale_color_manual(values = brand_colors) +
scale_x_date(date_labels = "%b %Y", date_breaks = "6 months") +
scale_y_continuous(limits = c(0, 110)) +
labs(
title = "Peak Search Interest by Brand",
subtitle = "Annotated peaks across the 5-year window",
x = NULL,
y = "Relative Search Interest (0–100)",
color = "Brand",
caption = "Source: Google Trends via gtrendsR"
) +
theme_minimal(base_size = 12) +
theme(
plot.title = element_text(face = "bold", size = 14),
plot.subtitle = element_text(color = "gray50"),
axis.text.x = element_text(angle = 30, hjust = 1),
legend.position = "top"
)
Among the three brands, Lululemon consistently dominates U.S. search interest across the full five-year period, reflecting its status as the most established and widely recognized athleisure brand in the market. Its search peaks tend to align with key retail moments such as holiday shopping seasons and major product launches (e.g., the “We Made Too Much” sale events).
Gymshark shows meaningful but lower search volume, with growth driven largely by its social media and influencer-marketing model — notable spikes often correspond to its Black Friday sales, which the brand has turned into a major annual event.
Fabletics maintains a relatively steady but lower baseline, consistent with its subscription-model business that relies more on direct email and paid acquisition channels than organic search interest.
The brand with the highest peak search interest is identified in the annotated chart above. A reasonable hypothesis for Lululemon’s dominance is that its combination of in-store retail presence, strong brand community, and mainstream media coverage generates consistently higher search intent compared to the more digitally-native Gymshark and Fabletics.
Google Trends. (2024). Google Trends Tutorials [YouTube series]. Google Search Central. https://developers.google.com/search/blog/2024/09/google-trends-tutorials
Massicotte, P., & Eddelbuettel, D. (2023). gtrendsR: Perform and Display Google Trends Queries [R package]. https://cran.r-project.org/package=gtrendsR
Chan, M. (2019). Vignette: Google Trends with the gtrendsR package. https://martinctc.github.io/blog/vignette-google-trends-with-gtrendsr/