Skip to content

Instantly share code, notes, and snippets.

@jdavidson
Created February 28, 2015 22:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jdavidson/d1dcafe0281401b20082 to your computer and use it in GitHub Desktop.
Save jdavidson/d1dcafe0281401b20082 to your computer and use it in GitHub Desktop.
library(ggplot2)
library(ggthemes)
library(plyr)
library(dplyr)
library(tidyr)
library(lubridate)
library(scales)
library(reshape2)
set.seed(42)
wow <- .07
transaction_week <- .5
customer_churn_week <- .08
base_revenue <- 5000
start <- ymd("2014-09-01")
end <- start + weeks(22)
dates <- seq(start, end, by="weeks")
growth_rates <- c(1, 1 + rnorm(length(dates)-1, wow, wow / 4))
funnel <- data.frame(
week=dates,
revenue=base_revenue * cumprod(growth_rates),
asp=seq(15, 15 + .1 * (length(dates)-1), by=.1)) %>% mutate(
transactions=revenue / asp,
customers=transactions / transaction_week
)
rplot <- ggplot(funnel, aes(x=week, y=revenue)) + geom_line() + xlab("Date") +
ylab("Revenue") + scale_y_continuous(labels = dollar_format())
ggsave("revenue.png", rplot, width=640 / 72, height=400 / 72, dpi=72)
rplot
# Monthly Growth
(max(funnel$revenue) / min(funnel$revenue)) ^ (1 / (length(funnel$revenue) / 4)) - 1
# Annual Run Rate
max(funnel$revenue) * 52
funnel.cohort <- data.frame(expand.grid(week=dates, cohort=dates)) %>%
filter(cohort <= week) %>% arrange(week) %>% transform(revenue=0, customers=0, transactions=0)
funnel.cohort <- inner_join(funnel.cohort, select(funnel, week, asp))
for (date in dates) {
week_revenue <- as.numeric(funnel %>% filter(week == date) %>% select(revenue))
cohort_revenue <- as.numeric(funnel.cohort %>% filter(week == date) %>% summarize(revenue=sum(revenue)))
funnel.cohort[which(funnel.cohort$cohort == date), "revenue"] <- (week_revenue - cohort_revenue) * c(1,
cumprod(rep(1 - customer_churn_week, length(funnel.cohort[which(funnel.cohort$cohort == date), "week"]) - 1)))
}
funnel.cohort <- funnel.cohort %>% mutate(transactions = revenue / asp, customers=transactions / transaction_week)
blues <- colorRampPalette(c('light blue', 'dark blue'))
# include week before for better plot
x <- data.frame(week=head(dates,-1), cohort=tail(dates, -1), revenue=0, transactions=0, customers=0, asp=0)
funnel.cohort <- rbind(funnel.cohort, x)
cplot <- ggplot(funnel.cohort, aes(x=week, y=revenue, group=cohort, fill=as.factor(cohort))) +
geom_area() + scale_fill_manual(values = blues(length(dates))) + xlab("Date") +
ylab("Revenue") + scale_y_continuous(labels = dollar_format())
ggsave("revenue-cohort.png", cplot, width=640 / 72, height=400 / 72, dpi=72)
cplot
week_num <- data.frame(week=dates, week_num=seq(1,length(dates)))
cohort_num <- data.frame(cohort=dates, cohort_num=seq(1,length(dates)))
funnel.cohort <- data.frame(inner_join(inner_join(funnel.cohort, week_num), cohort_num))
funnel.month <- funnel.cohort %>%
group_by(month=floor(week_num / 4)) %>%
summarize(revenue=sum(revenue), transactions=sum(transactions), customers=sum(customers)) %>%
transform(asp=revenue/transactions)
funnel.cohort.month <- funnel.cohort %>%
group_by(month=floor(week_num / 4), cohort=floor(cohort_num / 4)) %>%
summarise(revenue=sum(revenue), transactions=sum(transactions), customers=sum(customers)) %>%
transform(asp=revenue/transactions)
months <- unique(funnel.cohort.month$month)
x <- data.frame(month=head(months,-1), cohort=tail(months, -1), revenue=0, transactions=0, customers=0, asp=0)
funnel.cohort.month <- rbind(funnel.cohort.month, x)
cmplot <- ggplot(funnel.cohort.month, aes(x=month, y=revenue, group=cohort, fill=as.factor(cohort))) +
geom_area() + scale_fill_manual(values = blues(length(unique(funnel.cohort.month$month)))) + xlab("Date") +
ylab("Revenue") + scale_y_continuous(labels = dollar_format())
ggsave("revenue-cohort-month.png", cmplot, width=640 / 72, height=400 / 72, dpi=72)
cmplot
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment