Skip to content

Commit

Permalink
feat: enable baseline_level param and NULL solID for decomp_plot() + …
Browse files Browse the repository at this point in the history
…docs: update robyn_response() examples (#923)
  • Loading branch information
laresbernardo authored Feb 17, 2024
1 parent dcd3f47 commit 71a949c
Show file tree
Hide file tree
Showing 6 changed files with 143 additions and 71 deletions.
2 changes: 1 addition & 1 deletion R/DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Package: Robyn
Type: Package
Title: Semi-Automated Marketing Mix Modeling (MMM) from Meta Marketing Science
Version: 3.10.5.9014
Version: 3.10.5.9015
Authors@R: c(
person("Gufeng", "Zhou", , "[email protected]", c("cre","aut")),
person("Leonel", "Sentana", , "[email protected]", c("aut")),
Expand Down
2 changes: 1 addition & 1 deletion R/R/auxiliary.R
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ baseline_vars <- function(InputCollect, baseline_level) {
stopifnot(baseline_level %in% 0:5)
x <- ""
if (baseline_level >= 1)
x <- c(x, "(Intercept)")
x <- c(x, "(Intercept)", "intercept")
if (baseline_level >= 2)
x <- c(x, "trend")
if (baseline_level >= 3)
Expand Down
16 changes: 14 additions & 2 deletions R/R/plots.R
Original file line number Diff line number Diff line change
Expand Up @@ -1485,8 +1485,13 @@ ts_validation <- function(OutputModels, quiet = FALSE, ...) {
#' @param solID Character vector. Model IDs to plot.
#' @param exclude Character vector. Manually exclude variables from plot.
#' @export
decomp_plot <- function(InputCollect, OutputCollect, solID = NULL, exclude = NULL) {
decomp_plot <- function(
InputCollect, OutputCollect, solID = NULL,
exclude = NULL, baseline_level = 0) {
if (is.null(solID) && length(OutputCollect$allSolutions) == 1)
solID <- OutputCollect$allSolutions
check_opts(solID, OutputCollect$allSolutions)
bvars <- baseline_vars(InputCollect, baseline_level)
intType <- str_to_title(case_when(
InputCollect$intervalType %in% c("month", "week") ~ paste0(InputCollect$intervalType, "ly"),
InputCollect$intervalType == "day" ~ "daily",
Expand All @@ -1501,7 +1506,14 @@ decomp_plot <- function(InputCollect, OutputCollect, solID = NULL, exclude = NUL
) %>%
tidyr::gather("variable", "value", -.data$ds, -.data$solID, -.data$dep_var) %>%
filter(!.data$variable %in% exclude) %>%
mutate(variable = factor(.data$variable, levels = rev(unique(.data$variable))))
mutate(variable = ifelse(
.data$variable %in% bvars, paste0("Baseline_L", baseline_level), as.character(.data$variable))) %>%
group_by(.data$solID, .data$ds, .data$variable) %>%
summarise(value = sum(.data$value, na.rm = TRUE),
value = sum(.data$value, na.rm = TRUE),
.groups = "drop") %>%
arrange(abs(.data$value)) %>%
mutate(variable = factor(.data$variable, levels = unique(.data$variable)))
p <- ggplot(df, aes(x = .data$ds, y = .data$value, fill = .data$variable)) +
facet_grid(.data$solID ~ .) +
labs(
Expand Down
89 changes: 58 additions & 31 deletions R/R/response.R
Original file line number Diff line number Diff line change
Expand Up @@ -23,56 +23,83 @@
#' @examples
#' \dontrun{
#' # Having InputCollect and OutputCollect objects
#' ## Recreate original saturation curve
#' Response <- robyn_response(
#' InputCollect = InputCollect,
#' OutputCollect = OutputCollect,
#' select_model = select_model,
#' metric_name = "facebook_S"
#' )
#' Response$plot
#'
#' # Get marginal response (mResponse) and marginal ROI (mROI) for
#' # the next 1k on 80k for search_S
#' spend1 <- 80000
#' ## Or you can call a JSON file directly (a bit slower)
#' # Response <- robyn_response(
#' # json_file = "your_json_path.json",
#' # dt_input = dt_simulated_weekly,
#' # dt_holidays = dt_prophet_holidays,
#' # metric_name = "facebook_S"
#' # )
#'
#' ## Get the "next 100 dollar" marginal response on Spend1
#' Spend1 <- 20000
#' Response1 <- robyn_response(
#' InputCollect = InputCollect,
#' OutputCollect = OutputCollect,
#' metric_name = "search_S",
#' metric_value = spend1
#' )$response
#' # Get ROI for 80k
#' Response1 / spend1 # ROI for search 80k
#' select_model = select_model,
#' metric_name = "facebook_S",
#' metric_value = Spend1, # total budget for date_range
#' date_range = "last_1" # last two periods
#' )
#' Response1$plot
#'
#' # Get response for 81k
#' spend2 <- spend1 + 1000
#' Spend2 <- Spend1 + 100
#' Response2 <- robyn_response(
#' InputCollect = InputCollect,
#' OutputCollect = OutputCollect,
#' metric_name = "search_S",
#' metric_value = spend2
#' )$response
#' select_model = select_model,
#' metric_name = "facebook_S",
#' metric_value = Spend2,
#' date_range = "last_1"
#' )
#' # ROAS for the 100$ from Spend1 level
#' (Response2$response_total - Response1$response_total) / (Spend2 - Spend1)
#'
#' # Get ROI for 81k
#' Response2 / spend2 # ROI for search 81k
#' # Get marginal response (mResponse) for the next 1k on 80k
#' Response2 - Response1
#' # Get marginal ROI (mROI) for the next 1k on 80k
#' (Response2 - Response1) / (spend2 - spend1)
#' ## Get response from for a given budget and date_range
#' Spend3 <- 100000
#' Response3 <- robyn_response(
#' InputCollect = InputCollect,
#' OutputCollect = OutputCollect,
#' select_model = select_model,
#' metric_name = "facebook_S",
#' metric_value = Spend3, # total budget for date_range
#' date_range = "last_5" # last 5 periods
#' )
#' Response3$plot
#'
#' # Example of getting paid media exposure response curves
#' imps <- 1000000
#' ## Example of getting paid media exposure response curves
#' imps <- 10000000
#' response_imps <- robyn_response(
#' InputCollect = InputCollect,
#' OutputCollect = OutputCollect,
#' select_model = select_model,
#' metric_name = "facebook_I",
#' metric_value = imps
#' )$response
#' response_per_1k_imps <- response_imps / imps * 1000
#' response_per_1k_imps
#' )
#' response_imps$response_total / imps * 1000
#' response_imps$plot
#'
#' # Get response for 80k for search_S from the a certain model SolID
#' # in the current model output in the global environment
#' robyn_response(
#' ## Example of getting organic media exposure response curves
#' sendings <- 30000
#' response_sending <- robyn_response(
#' InputCollect = InputCollect,
#' OutputCollect = OutputCollect,
#' metric_name = "search_S",
#' metric_value = 80000,
#' dt_hyppar = OutputCollect$resultHypParam,
#' dt_coef = OutputCollect$xDecompAgg
#' select_model = select_model,
#' metric_name = "newsletter",
#' metric_value = sendings
#' )
#' # response per 1000 sendings
#' response_sending$response_total / sendings * 1000
#' response_sending$plot
#' }
#' @return List. Response value and plot. Class: \code{robyn_response}.
#' @export
Expand Down
8 changes: 7 additions & 1 deletion R/man/robyn_outputs.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

97 changes: 62 additions & 35 deletions R/man/robyn_response.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 71a949c

Please sign in to comment.