Метрики монетизации pt3

Разбор домашнего задания

# Подключаем библиотеки
library(tidyverse)
library(plotly)
library(kableExtra)

# Загружаем данные
installs <- read_csv("./data/installs.csv")
payments <- read_csv("./data/payments_custom.csv")

# Выделяем инсталлы в июне
installs_june <- installs %>%
  filter(dt >= "2022-06-01", dt < "2022-07-01")

level 2 (HNTR)

На основе данных по платежам нарисуйте area plot подневную структуру гросса проекта, в котором цветами выделите группы пользователей по количеству дней с момента инсталла:

  • группа 1: 0 дней с инсталла

  • группа 2: 1-7 дней с момента инсталла

  • группа 3: 8-28 дней с инсталла

  • группа 4: более 28 дней с инсталла

Решение аналогично такому же заданию на расчет структуры DAU.

Решение:

level 3 (HMP)

Сделайте табличку монетизации для июньских и июльских когорт пользователей. В табличке должны быть следующие метрики:

  • total_users: всего пользователей когорты
  • n_payers: количество платящих
  • conversion: конверсия в платящих
  • gross: сколько всего заплатили
  • ARPU
  • ARPPU
  • AOV (average order value): размер среднего платежа (средний чек)
  • AvPurchases: среднее количество платежей на пользователя

По строкам – пользователи, пришедшие в июне и июле, две строки.

# Считаем количество пользователей по платформам
installs_m <- installs %>%
  filter(dt >= "2022-06-01", dt < "2022-07-25") %>%
  mutate(month = month(dt, label = TRUE, locale = 'en_US.UTF-8', abbr = FALSE))

installs_m_stat <- installs_m %>%
  group_by(month) %>% 
  summarise(total_users = n_distinct(user_pseudo_id), .groups = "drop")

# Объединяем платежи с инсталлами за июнь
payments_m <- payments %>%
  inner_join(installs_m, by = c("user_pseudo_id", "platform")) %>%
  mutate(lifetime = as.integer(as.Date(pay_dt) - as.Date(dt)))
## Warning in inner_join(., installs_m, by = c("user_pseudo_id", "platform")): Detected an unexpected many-to-many relationship between `x` and `y`.
## ℹ Row 1199 of `x` matches multiple rows in `y`.
## ℹ Row 106046 of `y` matches multiple rows in `x`.
## ℹ If a many-to-many relationship is expected, set `relationship =
##   "many-to-many"` to silence this warning.
# Фильтруем только платежи в первые 7 дней
payments_m_stat <- payments_m %>%
  filter(lifetime %in% 0:7) %>%
  group_by(month) %>%
  summarise(
    n_payers = n_distinct(user_pseudo_id),
    gross = sum(gross, na.rm = TRUE),
    n_transactions = n()
  )

# Объединяем статистику установок и платежей
monetization_m <- installs_m_stat %>%
  left_join(payments_m_stat, by = 'month') %>%
  mutate(
    conversion = round(n_payers / total_users, 3),
    ARPU = round(gross / total_users, 3),
    ARPPU = round(gross / n_payers, 1),
    AOV = round(gross / n_transactions, 1),
    AvPurchases = round(n_transactions / n_payers, 1)
  )

kable(monetization_m) %>%
  kable_styling(font_size = 10)
month total_users n_payers gross n_transactions conversion ARPU ARPPU AOV AvPurchases
June 110780 2059 42518.46 5217 0.019 0.384 20.7 8.1 2.5
July 11843 217 4581.76 757 0.018 0.387 21.1 6.1 3.5

level 4 (UV)

Постройте воронку платежей (возьмите первые 10 платежей) в когорте июньских пользователей, с разбивкой по платформам. Попробуйте сделать два графика – один с долями от первого шага, другой – с долями от предыдущего шага.

Для обращения к значению в предыдущей ячейки питонистам поможет метод shift(). Тем, кто пишет на tidyverse R – функция lag().

users_june <- installs %>%
  filter(dt < as.Date("2022-07-01")) %>%
  distinct(user_pseudo_id) %>%
  pull(user_pseudo_id)

# Сортируем платежи по пользователю и времени транзакции
payments_june <- payments %>%
  filter(user_pseudo_id %in% users_june) %>%
  arrange(user_pseudo_id, ts) %>%
  group_by(user_pseudo_id) %>%
  mutate(payment_number = row_number()) %>%
  ungroup()

# Фильтруем только первые 10 платежей
payment_funnel <- payments_june %>%
  filter(payment_number <= 10) %>%
  group_by(platform, payment_number) %>%
  summarise(n_users = n_distinct(user_pseudo_id), .groups = "drop")

# Добавляем общее количество пользователей и считаем долю
payment_funnel <- payment_funnel %>%
  group_by(platform) %>%
  mutate(
    total_users = n_users[payment_number == 1],
    share = n_users / total_users,
    n_users_prev = lag(n_users, n = 1),
    share_prev = n_users / n_users_prev,
  )

# Строим воронку платежей
plot_ly(payment_funnel,  x = ~payment_number,  y = ~share,  type = "bar", color = ~platform) %>%
  layout(title = "Воронка платежей") %>%  
  config(displayModeBar = FALSE)
## Warning in RColorBrewer::brewer.pal(N, "Set2"): minimal value for n is 3, returning requested palette with 3 different levels
## Warning in RColorBrewer::brewer.pal(N, "Set2"): minimal value for n is 3, returning requested palette with 3 different levels
# Строим воронку платежей
plot_ly(payment_funnel,  x = ~payment_number,  y = ~share_prev,  type = "bar", color = ~platform) %>%
  layout(title = "Воронка платежей, доля от предыдущего шага") %>%  
  config(displayModeBar = FALSE)
## Warning: Ignoring 2 observations
## Warning: minimal value for n is 3, returning requested palette with 3 different levels
## Warning: minimal value for n is 3, returning requested palette with 3 different levels

level 5 (N)

Постройте график накопительной конверсии в когорте июньских пользователей с разбивкой по источнику (media_source) пользователей.

Для этого надо сначала посчитать, в какой день от инсталла пользователь сделал первый платеж (lifetime). Потом посчитать, сколько пользователей сделало первый платеж в 0-30 дни от инсталла (new payers). Посчитать накопительную сумму по количеству пользователей (cumulative new payers). Посчитать отношение cumulative new payers / total users Нарисовать график.

# Фильтруем инсталлы до июля
installs_june <- installs %>%
  filter(dt < as.Date("2022-07-01"))

# Первый платёж каждого пользователя
first_payment <- payments %>%
  group_by(user_pseudo_id) %>%
  summarise(pay_dt_first = min(pay_dt), .groups = "drop")

# оставляем только июньских пользователей, вычисляем лайфтайм
first_payment <- first_payment%>%
  inner_join(installs_june %>% select(user_pseudo_id, dt, media_source), by = "user_pseudo_id") %>%
  mutate(lifetime = as.integer(difftime(pay_dt_first, dt, units = "days"))) %>%
  filter(lifetime %in% 0:7)

# Агрегация по источникам и лайфтаймам
first_payment_stat <- first_payment %>%
  group_by(media_source, lifetime) %>%
  summarise(new_payers = n_distinct(user_pseudo_id), .groups = "drop") %>%
  arrange(media_source, lifetime) %>%
  group_by(media_source) %>%
  mutate(new_payers_cum = cumsum(new_payers)) %>%
  ungroup()

# Кол-во инсталлов по источникам
installs_june_stat <- installs_june %>%
  group_by(media_source) %>%
  summarise(total_installs = n_distinct(user_pseudo_id), .groups = "drop")

# Объединение и расчет кумулятивной конверсии
first_payment_stat <- installs_june_stat %>%
  left_join(first_payment_stat, by = "media_source") %>%
  mutate(conversion_cum = new_payers_cum / total_installs)

# Визуализация
plot_ly(
  data = first_payment_stat,
  x = ~lifetime, y = ~conversion_cum, color = ~media_source,
  type = 'scatter', mode = 'lines'
) %>%
  layout(
    title = "Конверсия в платящих по источникам трафика",
    yaxis = list(rangemode = 'tozero')
  )