| Title: | Assess the Business Impact of Classification Models |
|---|---|
| Description: | Calculate and visualise the financial impact of using a classification model to prioritise or target cases. Although originally designed for customer churn, the same tools apply to many binary classification problems, including fraud detection, credit default, lead scoring and marketing response, upsell and cross-sell, and predictive maintenance. Provides cost, revenue, profit and return-on-investment curves as a function of the share of cases targeted, cumulative gains and lift, marginal profit per bin, and confusion-matrix based payoff across probability thresholds. Also includes 'ggplot2' 'autoplot()' methods and an interactive 'shiny' application for exploring the results. |
| Authors: | Peer Christensen [aut, cre] |
| Maintainer: | Peer Christensen <[email protected]> |
| License: | MIT + file LICENSE |
| Version: | 1.2.0 |
| Built: | 2026-07-20 15:39:14 UTC |
| Source: | https://github.com/peerchristensen/modelimpact |
Resamples the observations with replacement a number of times, recomputes the cumulative profit curve for each resample, and returns pointwise quantile bands. This turns the single profit curve from [profit()] into a range, making it clear how much of the curve's shape is signal versus sampling noise.
bootstrap_profit( x, fixed_cost = 0, var_cost = 0, tp_val = 0, prob_col = NA, truth_col = NA, positive = "Yes", n_boot = 200, probs = c(0.05, 0.5, 0.95) )bootstrap_profit( x, fixed_cost = 0, var_cost = 0, tp_val = 0, prob_col = NA, truth_col = NA, positive = "Yes", n_boot = 200, probs = c(0.05, 0.5, 0.95) )
x |
A data frame containing predicted probabilities of a target event and the actual outcome/class. |
fixed_cost |
Fixed cost (e.g. of a campaign). |
var_cost |
Variable cost (e.g. discount offered) per targeted customer. Either a single value or an unquoted column name (or vector) giving a per-observation cost. |
tp_val |
The value of a True Positive. Either a single value or an unquoted column name (or vector) giving a per-observation value. |
prob_col |
The unquoted name of the column with probabilities of the event of interest. |
truth_col |
The unquoted name of the column with the actual outcome/class. |
positive |
The value in ‘truth_col' that identifies the event of interest. Defaults to ’Yes'. |
n_boot |
Number of bootstrap resamples. Defaults to 200. |
probs |
Lower, middle and upper quantiles for the bands. Defaults to 'c(0.05, 0.5, 0.95)'. |
A data frame with the following columns:
row = row numbers
prop_pop = proportion of the population targeted (row / n)
lower = lower quantile of profit across resamples
median = median profit across resamples
upper = upper quantile of profit across resamples
bootstrap_profit(predictions, fixed_cost = 1000, var_cost = 100, tp_val = 2000, prob_col = Yes, truth_col = Churn, n_boot = 100)bootstrap_profit(predictions, fixed_cost = 1000, var_cost = 100, tp_val = 2000, prob_col = Yes, truth_col = Churn, n_boot = 100)
Summarises the two key operating points of the cumulative profit curve produced by [profit()]: the point of maximum profit (the recommended share of customers to target) and the break-even point (the largest share that can be targeted while still turning a profit).
break_even( x, fixed_cost = 0, var_cost = 0, tp_val = 0, prob_accept = 1, prob_col = NA, truth_col = NA, positive = "Yes" )break_even( x, fixed_cost = 0, var_cost = 0, tp_val = 0, prob_accept = 1, prob_col = NA, truth_col = NA, positive = "Yes" )
x |
A data frame containing predicted probabilities of a target event and the actual outcome/class. |
fixed_cost |
Fixed cost (e.g. of a campaign). |
var_cost |
Variable cost (e.g. discount offered) per targeted customer. Either a single value or an unquoted column name (or vector) giving a per-observation cost. |
tp_val |
The value of a True Positive. Either a single value or an unquoted column name (or vector) giving a per-observation value. |
prob_accept |
Probability of the offer being accepted. Variable cost is only incurred when accepted. Defaults to 1. |
prob_col |
The unquoted name of the column with probabilities of the event of interest. |
truth_col |
The unquoted name of the column with the actual outcome/class. |
positive |
The value in ‘truth_col' that identifies the event of interest. Defaults to ’Yes'. |
A one-row data frame with the following columns:
optimal_row = row at which profit is maximised
optimal_pct = share of the population targeted at maximum profit
max_profit = the maximum profit
breakeven_row = last row at which cumulative profit is still non-negative
breakeven_pct = share of the population targeted at the break-even point
break_even(predictions, fixed_cost = 1000, var_cost = 100, tp_val = 2000, prob_col = Yes, truth_col = Churn)break_even(predictions, fixed_cost = 1000, var_cost = 100, tp_val = 2000, prob_col = Yes, truth_col = Churn)
Real campaigns rarely get to target the profit-maximising share of the population; they get a fixed pot of money. 'budget_profit()' answers *"given this budget, how many cases can we action, and what is the best profit we can make?"* for a single budget, while [budget_frontier()] sweeps a range of budgets to show how achievable profit grows as the budget increases.
budget_profit( x, budget, fixed_cost = 0, var_cost = 0, tp_val = 0, prob_accept = 1, prob_col = NA, truth_col = NA, positive = "Yes" ) budget_frontier( x, fixed_cost = 0, var_cost = 0, tp_val = 0, prob_accept = 1, prob_col = NA, truth_col = NA, positive = "Yes", budgets = NULL, n_points = 50 )budget_profit( x, budget, fixed_cost = 0, var_cost = 0, tp_val = 0, prob_accept = 1, prob_col = NA, truth_col = NA, positive = "Yes" ) budget_frontier( x, fixed_cost = 0, var_cost = 0, tp_val = 0, prob_accept = 1, prob_col = NA, truth_col = NA, positive = "Yes", budgets = NULL, n_points = 50 )
x |
A data frame containing predicted probabilities of a target event and the actual outcome/class. |
budget |
The total amount available to spend (fixed plus variable costs). |
fixed_cost |
Fixed cost (e.g. of a campaign). |
var_cost |
Variable cost (e.g. discount offered) per targeted customer. Either a single value or an unquoted column name (or vector) giving a per-observation cost. |
tp_val |
The value of a True Positive. Either a single value or an unquoted column name (or vector) giving a per-observation value. |
prob_accept |
Probability of the offer being accepted. Variable cost is only incurred when accepted. Defaults to 1. |
prob_col |
The unquoted name of the column with probabilities of the event of interest. |
truth_col |
The unquoted name of the column with the actual outcome/class. |
positive |
The value in ‘truth_col' that identifies the event of interest. Defaults to ’Yes'. |
budgets |
A numeric vector of budgets to evaluate. When 'NULL' (the default) an evenly spaced sequence from 0 to the cost of targeting everyone is used. |
n_points |
Number of budgets in the automatically generated sequence when 'budgets' is 'NULL'. Defaults to 50. |
Cases are ranked from most to least likely to be a positive, then targeted from the top down until the budget is exhausted. Because doing nothing is always an option, the reported profit is never negative: if no affordable campaign is profitable, the functions report targeting no one (a profit of zero).
'budget_profit()' returns a one-row data frame; [budget_frontier()] returns one row per budget (class 'mi_budget'). Both have the columns:
budget = the budget considered
n_targeted = number of cases targeted at the best affordable operating point
prop_pop = share of the population targeted (n_targeted / n)
cost = amount actually spent
profit = best profit achievable within the budget
roi = return on investment at that point
capture = proportion of all positives captured at that point
budget_profit(predictions, budget = 50000, fixed_cost = 1000, var_cost = 100, tp_val = 2000, prob_col = Yes, truth_col = Churn) budget_frontier(predictions, fixed_cost = 1000, var_cost = 100, tp_val = 2000, prob_col = Yes, truth_col = Churn)budget_profit(predictions, budget = 50000, fixed_cost = 1000, var_cost = 100, tp_val = 2000, prob_col = Yes, truth_col = Churn) budget_frontier(predictions, fixed_cost = 1000, var_cost = 100, tp_val = 2000, prob_col = Yes, truth_col = Churn)
Computes a targeting curve for two or more models so they can be compared and overlaid on a single plot. Rather than picking a model on AUC alone, this lets you choose the one that produces the most profit (or the steepest gains, lift or ROI) at the share of customers you intend to target.
compare_models( x, prob_cols, truth_col = NA, metric = c("profit", "gains", "lift", "roi"), fixed_cost = 0, var_cost = 0, tp_val = 0, positive = "Yes" )compare_models( x, prob_cols, truth_col = NA, metric = c("profit", "gains", "lift", "roi"), fixed_cost = 0, var_cost = 0, tp_val = 0, positive = "Yes" )
x |
A data frame containing one probability column per model and a shared actual outcome/class. |
prob_cols |
A character vector of column names holding each model's predicted probabilities. |
truth_col |
The unquoted name of the column with the actual outcome/class. |
metric |
The curve to compute: one of "profit", "gains", "lift" or "roi". |
fixed_cost |
Fixed cost (used by "profit" and "roi"). |
var_cost |
Variable cost per targeted customer (used by "profit" and "roi"). |
tp_val |
The average value of a True Positive (used by "profit" and "roi"). |
positive |
The value in ‘truth_col' that identifies the event of interest. Defaults to ’Yes'. |
A data frame with the following columns:
model = the model (column) name
row = row numbers
prop_pop = proportion of the population targeted (row / n)
value = the chosen metric at that point
compare_models(predictions, prob_cols = c("Yes", "No"), truth_col = Churn, metric = "gains")compare_models(predictions, prob_cols = c("Yes", "No"), truth_col = Churn, metric = "gains")
Classifies observations at a single probability threshold, returns the resulting confusion matrix (TP/FP/TN/FN) and the associated payoff. This is the single-threshold companion to [profit_thresholds()], which sweeps every threshold, and uses the same value model.
confusion_payoff( x, threshold = 0.5, var_cost = 0, prob_accept = 1, tp_val = 0, fp_val = 0, tn_val = 0, fn_val = 0, prob_col = NA, truth_col = NA, positive = "Yes" )confusion_payoff( x, threshold = 0.5, var_cost = 0, prob_accept = 1, tp_val = 0, fp_val = 0, tn_val = 0, fn_val = 0, prob_col = NA, truth_col = NA, positive = "Yes" )
x |
A data frame containing predicted probabilities of a target event and the actual outcome/class. |
threshold |
Probability cutoff above which an observation is classified as the positive class. |
var_cost |
Variable cost (e.g. of a campaign offer). |
prob_accept |
Probability of offer being accepted. Defaults to 1. |
tp_val |
The average value of a True Positive. 'var_cost' is automatically subtracted. |
fp_val |
The average cost of a False Positive. 'var_cost' is automatically subtracted. |
tn_val |
The average value of a True Negative. |
fn_val |
The average cost of a False Negative. |
prob_col |
The unquoted name of the column with probabilities of the event of interest. |
truth_col |
The unquoted name of the column with the actual outcome/class. |
positive |
The value in ‘truth_col' that identifies the event of interest. Defaults to ’Yes'. |
A one-row data frame with the following columns:
threshold = the threshold used
tp = number of true positives
fp = number of false positives
tn = number of true negatives
fn = number of false negatives
payoff = total payoff at the threshold
confusion_payoff(predictions, threshold = 0.3, var_cost = 100, prob_accept = .8, tp_val = 2000, fp_val = 0, tn_val = 0, fn_val = -2000, prob_col = Yes, truth_col = Churn)confusion_payoff(predictions, threshold = 0.3, var_cost = 100, prob_accept = .8, tp_val = 2000, fp_val = 0, tn_val = 0, fn_val = -2000, prob_col = Yes, truth_col = Churn)
Calculates cost and revenue after sorting observations.
cost_revenue( x, fixed_cost = 0, var_cost = 0, tp_val = 0, prob_accept = 1, prob_col = NA, truth_col = NA, positive = "Yes", ci = FALSE, n_boot = 1000, conf_level = 0.95 )cost_revenue( x, fixed_cost = 0, var_cost = 0, tp_val = 0, prob_accept = 1, prob_col = NA, truth_col = NA, positive = "Yes", ci = FALSE, n_boot = 1000, conf_level = 0.95 )
x |
A data frame containing predicted probabilities of a target event and the actual outcome/class. |
fixed_cost |
Fixed cost (e.g. of a campaign) |
var_cost |
Variable cost (e.g. discount offered). Either a single value applied to every case, or an unquoted column name (or vector) giving a per-observation cost. |
tp_val |
The value of a True Positive. Either a single value applied to every case, or an unquoted column name (or vector) giving a per-observation value. |
prob_accept |
Probability of the offer being accepted. Variable cost is only incurred when accepted. Defaults to 1. |
prob_col |
The unquoted name of the column with probabilities of the event of interest. |
truth_col |
The unquoted name of the column with the actual outcome/class. |
positive |
The value in ‘truth_col' that identifies the event of interest. Defaults to ’Yes'. |
ci |
Add bootstrap confidence bands (for the revenue curve)? When 'TRUE', the returned data frame gains '.lower' and '.upper' columns and 'autoplot()' draws a ribbon. Defaults to 'FALSE'. |
n_boot |
Number of bootstrap resamples used when 'ci = TRUE'. Defaults to 1000. |
conf_level |
Width of the confidence band when 'ci = TRUE'. Defaults to 0.95. |
A data frame with the following columns:
row = row numbers
pct = percentiles
cost_sum = cumulated costs
cum_rev = cumulated revenue
cost_revenue(predictions, fixed_cost = 1000, var_cost = 100, tp_val = 2000, prob_col = Yes, truth_col = Churn)cost_revenue(predictions, fixed_cost = 1000, var_cost = 100, tp_val = 2000, prob_col = Yes, truth_col = Churn)
Calculates a cumulative gains curve after sorting observations by descending predicted probability. The gain at a given point is the proportion of all actual positives (events) that have been captured by targeting the top rows.
cumulative_gains( x, prob_col = NA, truth_col = NA, positive = "Yes", ci = FALSE, n_boot = 1000, conf_level = 0.95 )cumulative_gains( x, prob_col = NA, truth_col = NA, positive = "Yes", ci = FALSE, n_boot = 1000, conf_level = 0.95 )
x |
A data frame containing predicted probabilities of a target event and the actual outcome/class. |
prob_col |
The unquoted name of the column with probabilities of the event of interest. |
truth_col |
The unquoted name of the column with the actual outcome/class. |
positive |
The value in ‘truth_col' that identifies the event of interest. Defaults to ’Yes'. |
ci |
Add bootstrap confidence bands? When 'TRUE', the returned data frame gains '.lower' and '.upper' columns and 'autoplot()' draws a ribbon. Defaults to 'FALSE'. |
n_boot |
Number of bootstrap resamples used when 'ci = TRUE'. Defaults to 1000. |
conf_level |
Width of the confidence band when 'ci = TRUE'. Defaults to 0.95. |
A data frame with the following columns:
row = row numbers
pct = percentiles
prop_pop = proportion of the population targeted (row / n)
cum_events = cumulated number of actual positives captured
gain = proportion of all positives captured (cum_events / total positives)
baseline = expected gain from random targeting (equal to prop_pop)
cumulative_gains(predictions, prob_col = Yes, truth_col = Churn)cumulative_gains(predictions, prob_col = Yes, truth_col = Churn)
Renders a ready-made, parameterised quarto report bundled with the package. The report pulls together the headline 'impact_summary()' and the cost/revenue, profit, ROI, gains, lift and marginal-profit views (plus a budget section when a 'budget' is supplied) into a single HTML document.
impact_report( x, prob_col, truth_col, positive = "Yes", fixed_cost = 0, var_cost = 0, tp_val = 0, prob_accept = 1, budget = NULL, output_file = "impact-report.html", quiet = TRUE )impact_report( x, prob_col, truth_col, positive = "Yes", fixed_cost = 0, var_cost = 0, tp_val = 0, prob_accept = 1, budget = NULL, output_file = "impact-report.html", quiet = TRUE )
x |
A data frame containing predicted probabilities of a target event and the actual outcome/class. |
prob_col |
The unquoted (or quoted) name of the column with the probabilities of the event of interest. |
truth_col |
The unquoted (or quoted) name of the column with the actual outcome/class. |
positive |
The value in 'truth_col' that identifies the event of interest. |
fixed_cost |
Fixed cost (e.g. of a campaign). |
var_cost |
Variable cost per targeted case (a single value). |
tp_val |
The value of a True Positive (a single value). |
prob_accept |
Probability of the offer being accepted. Defaults to 1. |
budget |
Optional budget. When supplied, a budget section is added to the report. |
output_file |
Path of the HTML file to create. Defaults to '"impact-report.html"' in the working directory. |
quiet |
Suppress Quarto's rendering output? Defaults to 'TRUE'. |
Requires the quarto R package and a working [Quarto](https://quarto.org) installation.
The path to the rendered report, invisibly.
## Not run: impact_report(predictions, prob_col = Yes, truth_col = Churn, fixed_cost = 1000, var_cost = 100, tp_val = 2000, output_file = "churn-impact.html") ## End(Not run)## Not run: impact_report(predictions, prob_col = Yes, truth_col = Churn, fixed_cost = 1000, var_cost = 100, tp_val = 2000, output_file = "churn-impact.html") ## End(Not run)
Rolls the ranking-based views (profit, ROI, gains and break-even) up into a single row of headline numbers for reporting. It answers: what share of customers should we target, how much profit does that make, what return does it represent, how many churners do we catch, how far can we go before losing money, and what happens if we simply target everyone.
impact_summary( x, fixed_cost = 0, var_cost = 0, tp_val = 0, prob_accept = 1, prob_col = NA, truth_col = NA, positive = "Yes" )impact_summary( x, fixed_cost = 0, var_cost = 0, tp_val = 0, prob_accept = 1, prob_col = NA, truth_col = NA, positive = "Yes" )
x |
A data frame containing predicted probabilities of a target event and the actual outcome/class. |
fixed_cost |
Fixed cost (e.g. of a campaign). |
var_cost |
Variable cost (e.g. discount offered) per targeted customer. Either a single value or an unquoted column name (or vector) giving a per-observation cost. |
tp_val |
The value of a True Positive. Either a single value or an unquoted column name (or vector) giving a per-observation value. |
prob_accept |
Probability of the offer being accepted. Variable cost is only incurred when accepted. Defaults to 1. |
prob_col |
The unquoted name of the column with probabilities of the event of interest. |
truth_col |
The unquoted name of the column with the actual outcome/class. |
positive |
The value in ‘truth_col' that identifies the event of interest. Defaults to ’Yes'. |
A one-row data frame with the following columns:
optimal_pct = share of the population targeted at maximum profit
max_profit = the maximum profit
roi_at_optimum = ROI at the maximum-profit point
capture_at_optimum = proportion of all positives captured at that point
breakeven_pct = largest share that can be targeted while staying profitable
profit_target_all = profit if every customer is targeted
impact_summary(predictions, fixed_cost = 1000, var_cost = 100, tp_val = 2000, prob_col = Yes, truth_col = Churn)impact_summary(predictions, fixed_cost = 1000, var_cost = 100, tp_val = 2000, prob_col = Yes, truth_col = Churn)
Calculates a cumulative lift curve after sorting observations by descending predicted probability. Lift is the ratio between the proportion of positives captured by the model and the proportion that would be expected from random targeting. A lift of 1 is no better than random. Named 'lift_curve()' to avoid clashing with 'purrr::lift()'.
lift_curve( x, prob_col = NA, truth_col = NA, positive = "Yes", ci = FALSE, n_boot = 1000, conf_level = 0.95 )lift_curve( x, prob_col = NA, truth_col = NA, positive = "Yes", ci = FALSE, n_boot = 1000, conf_level = 0.95 )
x |
A data frame containing predicted probabilities of a target event and the actual outcome/class. |
prob_col |
The unquoted name of the column with probabilities of the event of interest. |
truth_col |
The unquoted name of the column with the actual outcome/class. |
positive |
The value in ‘truth_col' that identifies the event of interest. Defaults to ’Yes'. |
ci |
Add bootstrap confidence bands? When 'TRUE', the returned data frame gains '.lower' and '.upper' columns and 'autoplot()' draws a ribbon. Defaults to 'FALSE'. |
n_boot |
Number of bootstrap resamples used when 'ci = TRUE'. Defaults to 1000. |
conf_level |
Width of the confidence band when 'ci = TRUE'. Defaults to 0.95. |
A data frame with the following columns:
row = row numbers
pct = percentiles
prop_pop = proportion of the population targeted (row / n)
gain = proportion of all positives captured
lift = gain / prop_pop
lift_curve(predictions, prob_col = Yes, truth_col = Churn)lift_curve(predictions, prob_col = Yes, truth_col = Churn)
Splits observations into equally sized bins (deciles by default) after sorting by descending predicted probability, and calculates the profit contributed by each bin. This makes it easy to see where targeting additional customers stops paying off: the first bin whose 'marginal_profit' turns negative marks the point of diminishing returns. The cumulative sum of 'marginal_profit' reconciles with the cumulative profit reported by [profit()].
marginal_profit( x, fixed_cost = 0, var_cost = 0, tp_val = 0, prob_accept = 1, bins = 10, prob_col = NA, truth_col = NA, positive = "Yes" )marginal_profit( x, fixed_cost = 0, var_cost = 0, tp_val = 0, prob_accept = 1, bins = 10, prob_col = NA, truth_col = NA, positive = "Yes" )
x |
A data frame containing predicted probabilities of a target event and the actual outcome/class. |
fixed_cost |
Fixed cost (e.g. of a campaign). Charged once, to the first bin. |
var_cost |
Variable cost (e.g. discount offered) per targeted customer. Either a single value applied to every case, or an unquoted column name (or vector) giving a per-observation cost. |
tp_val |
The value of a True Positive. Either a single value applied to every case, or an unquoted column name (or vector) giving a per-observation value. |
prob_accept |
Probability of the offer being accepted. Variable cost is only incurred when accepted. Defaults to 1. |
bins |
Number of equally sized bins. Defaults to 10 (deciles). |
prob_col |
The unquoted name of the column with probabilities of the event of interest. |
truth_col |
The unquoted name of the column with the actual outcome/class. |
positive |
The value in ‘truth_col' that identifies the event of interest. Defaults to ’Yes'. |
A data frame with the following columns:
bin = bin number (1 = highest probabilities)
n = number of observations in the bin
events = number of actual positives in the bin
cost = cost incurred in the bin
revenue = revenue generated in the bin
marginal_profit = revenue - cost for the bin
cum_profit = cumulative profit up to and including the bin
marginal_profit(predictions, fixed_cost = 1000, var_cost = 100, tp_val = 2000, bins = 10, prob_col = Yes, truth_col = Churn)marginal_profit(predictions, fixed_cost = 1000, var_cost = 100, tp_val = 2000, bins = 10, prob_col = Yes, truth_col = Churn)
Every analysis function in the package returns a classed data frame that can
be visualised directly with autoplot(), for example
autoplot(profit(...)). The 'plot_*()' functions are thin,
back-compatible wrappers around the corresponding 'autoplot()' method.
ggplot2 is only required when a plot is actually drawn.
autoplot.mi_profit(object, ...) autoplot.mi_cost_revenue(object, ...) autoplot.mi_roi(object, ...) autoplot.mi_gains(object, ...) autoplot.mi_lift(object, ...) autoplot.mi_marginal(object, ...) autoplot.mi_thresholds(object, ...) autoplot.mi_roc(object, slope = NULL, ...) autoplot.mi_compare(object, ...) autoplot.mi_bootstrap(object, ...) autoplot.mi_budget(object, ...) autoplot.mi_value_gains(object, ...) autoplot.mi_qini(object, ...) plot_profit(data) plot_cost_revenue(data) plot_roi(data) plot_gains(data) plot_lift(data) plot_marginal(data) plot_thresholds(data) plot_roc(data, slope = NULL) plot_budget(data) plot_value_gains(data) plot_qini(data)autoplot.mi_profit(object, ...) autoplot.mi_cost_revenue(object, ...) autoplot.mi_roi(object, ...) autoplot.mi_gains(object, ...) autoplot.mi_lift(object, ...) autoplot.mi_marginal(object, ...) autoplot.mi_thresholds(object, ...) autoplot.mi_roc(object, slope = NULL, ...) autoplot.mi_compare(object, ...) autoplot.mi_bootstrap(object, ...) autoplot.mi_budget(object, ...) autoplot.mi_value_gains(object, ...) autoplot.mi_qini(object, ...) plot_profit(data) plot_cost_revenue(data) plot_roi(data) plot_gains(data) plot_lift(data) plot_marginal(data) plot_thresholds(data) plot_roc(data, slope = NULL) plot_budget(data) plot_value_gains(data) plot_qini(data)
object, data
|
The data frame returned by the matching modelimpact function (e.g. the output of [profit()] for 'autoplot()' / 'plot_profit()'). |
... |
Unused, for S3 compatibility. |
slope |
For ROC objects only: optional slope of an iso-profit line. When supplied, the cost-sensitive optimal operating point (maximising 'tpr - slope * fpr') is highlighted. The business-optimal slope equals '(cost_fp / value_fn) * (n_neg / n_pos)'. |
A 'ggplot' object.
Every analysis function returns a classed data frame. These methods let those results slot into tidyverse / tidymodels workflows:
## S3 method for class 'mi_profit' tidy(x, ...) ## S3 method for class 'mi_roi' tidy(x, ...) ## S3 method for class 'mi_cost_revenue' tidy(x, ...) ## S3 method for class 'mi_gains' tidy(x, ...) ## S3 method for class 'mi_lift' tidy(x, ...) ## S3 method for class 'mi_marginal' tidy(x, ...) ## S3 method for class 'mi_thresholds' tidy(x, ...) ## S3 method for class 'mi_bootstrap' tidy(x, ...) ## S3 method for class 'mi_budget' tidy(x, ...) ## S3 method for class 'mi_value_gains' tidy(x, ...) ## S3 method for class 'mi_qini' tidy(x, ...) ## S3 method for class 'mi_compare' tidy(x, ...) ## S3 method for class 'mi_roc' tidy(x, ...) ## S3 method for class 'mi_profit' glance(x, ...) ## S3 method for class 'mi_thresholds' glance(x, ...) ## S3 method for class 'mi_budget' glance(x, ...) ## S3 method for class 'mi_value_gains' glance(x, ...) ## S3 method for class 'mi_qini' glance(x, ...)## S3 method for class 'mi_profit' tidy(x, ...) ## S3 method for class 'mi_roi' tidy(x, ...) ## S3 method for class 'mi_cost_revenue' tidy(x, ...) ## S3 method for class 'mi_gains' tidy(x, ...) ## S3 method for class 'mi_lift' tidy(x, ...) ## S3 method for class 'mi_marginal' tidy(x, ...) ## S3 method for class 'mi_thresholds' tidy(x, ...) ## S3 method for class 'mi_bootstrap' tidy(x, ...) ## S3 method for class 'mi_budget' tidy(x, ...) ## S3 method for class 'mi_value_gains' tidy(x, ...) ## S3 method for class 'mi_qini' tidy(x, ...) ## S3 method for class 'mi_compare' tidy(x, ...) ## S3 method for class 'mi_roc' tidy(x, ...) ## S3 method for class 'mi_profit' glance(x, ...) ## S3 method for class 'mi_thresholds' glance(x, ...) ## S3 method for class 'mi_budget' glance(x, ...) ## S3 method for class 'mi_value_gains' glance(x, ...) ## S3 method for class 'mi_qini' glance(x, ...)
x |
A modelimpact result object. |
... |
Unused, for generic compatibility. |
* 'tidy()' returns the result as a plain tibble (dropping the modelimpact class), which is useful when passing the curve on to other tidy tools. * 'glance()' returns a one-row summary of the headline numbers for the objects where that makes sense ('profit()', 'profit_thresholds()', 'budget_frontier()', 'value_gains()' and 'qini_curve()').
'tidy()' returns a tibble; 'glance()' returns a one-row tibble.
p <- profit(predictions, fixed_cost = 1000, var_cost = 100, tp_val = 2000, prob_col = Yes, truth_col = Churn) tidy(p) glance(p)p <- profit(predictions, fixed_cost = 1000, var_cost = 100, tp_val = 2000, prob_col = Yes, truth_col = Churn) tidy(p) glance(p)
Computes payoff across a grid of classification thresholds and offer-acceptance probabilities, so the robustness of the optimal operating point can be judged at a glance (for example as a heatmap). Uses the same value model as [profit_thresholds()] and [confusion_payoff()].
payoff_grid( x, thresholds = seq(0, 1, 0.02), prob_accept = seq(0, 1, 0.1), var_cost = 0, tp_val = 0, fp_val = 0, tn_val = 0, fn_val = 0, prob_col = NA, truth_col = NA, positive = "Yes" )payoff_grid( x, thresholds = seq(0, 1, 0.02), prob_accept = seq(0, 1, 0.1), var_cost = 0, tp_val = 0, fp_val = 0, tn_val = 0, fn_val = 0, prob_col = NA, truth_col = NA, positive = "Yes" )
x |
A data frame containing predicted probabilities of a target event and the actual outcome/class. |
thresholds |
A vector of probability cutoffs to evaluate. Defaults to 'seq(0, 1, 0.02)'. |
prob_accept |
A vector of offer-acceptance probabilities to evaluate. Defaults to 'seq(0, 1, 0.1)'. |
var_cost |
Variable cost (e.g. of a campaign offer). |
tp_val |
The average value of a True Positive. 'var_cost' is automatically subtracted. |
fp_val |
The average cost of a False Positive. 'var_cost' is automatically subtracted. |
tn_val |
The average value of a True Negative. |
fn_val |
The average cost of a False Negative. |
prob_col |
The unquoted name of the column with probabilities of the event of interest. |
truth_col |
The unquoted name of the column with the actual outcome/class. |
positive |
The value in ‘truth_col' that identifies the event of interest. Defaults to ’Yes'. |
A data frame with the following columns:
threshold = classification threshold
prob_accept = offer-acceptance probability
payoff = payoff for that combination
payoff_grid(predictions, var_cost = 100, tp_val = 2000, fn_val = -2000, prob_col = Yes, truth_col = Churn)payoff_grid(predictions, var_cost = 100, tp_val = 2000, fn_val = -2000, prob_col = Yes, truth_col = Churn)
A dataset containing 2145 observations with four columns specifying predicted probabilities and predicted and actual class.
predictionspredictions
A data frame with 2145 rows and 4 variables:
Predicted class
Predicted probability of class 'No'
Predicted probability of class 'Yes'
Actual class
...
Calculates profit after sorting observations.
profit( x, fixed_cost = 0, var_cost = 0, tp_val = 0, prob_accept = 1, prob_col = NA, truth_col = NA, positive = "Yes", ci = FALSE, n_boot = 1000, conf_level = 0.95 )profit( x, fixed_cost = 0, var_cost = 0, tp_val = 0, prob_accept = 1, prob_col = NA, truth_col = NA, positive = "Yes", ci = FALSE, n_boot = 1000, conf_level = 0.95 )
x |
A data frame containing predicted probabilities of a target event and the actual outcome/class. |
fixed_cost |
Fixed cost (e.g. of a campaign) |
var_cost |
Variable cost (e.g. discount offered). Either a single value applied to every case, or an unquoted column name (or vector) giving a per-observation cost. |
tp_val |
The value of a True Positive. Either a single value applied to every case, or an unquoted column name (or vector) giving a per-observation value. |
prob_accept |
Probability of the offer being accepted. Variable cost is only incurred when accepted. Defaults to 1. |
prob_col |
The unquoted name of the column with probabilities of the event of interest. |
truth_col |
The unquoted name of the column with the actual outcome/class. |
positive |
The value in ‘truth_col' that identifies the event of interest. Defaults to ’Yes'. |
ci |
Add bootstrap confidence bands? When 'TRUE', the returned data frame gains '.lower' and '.upper' columns and 'autoplot()' draws a ribbon. Defaults to 'FALSE'. |
n_boot |
Number of bootstrap resamples used when 'ci = TRUE'. Defaults to 1000. |
conf_level |
Width of the confidence band when 'ci = TRUE'. Defaults to 0.95. |
A data frame with the following columns:
row = row numbers
pct = percentiles
profit = profit for number of rows selected
profit(predictions, fixed_cost = 1000, var_cost = 100, tp_val = 2000, prob_col = Yes, truth_col = Churn)profit(predictions, fixed_cost = 1000, var_cost = 100, tp_val = 2000, prob_col = Yes, truth_col = Churn)
Finds the optimal threshold (from a business perspective) for classifying churners.
profit_thresholds( x, var_cost = 0, prob_accept = 1, tp_val = 0, fp_val = 0, tn_val = 0, fn_val = 0, prob_col = NA, truth_col = NA, positive = "Yes" )profit_thresholds( x, var_cost = 0, prob_accept = 1, tp_val = 0, fp_val = 0, tn_val = 0, fn_val = 0, prob_col = NA, truth_col = NA, positive = "Yes" )
x |
A data frame containing predicted probabilities of a target event and the actual outcome/class. |
var_cost |
Variable cost (e.g. of a campaign offer). Either a single value applied to every case, or an unquoted column name (or vector) giving a per-observation cost. |
prob_accept |
Probability of offer being accepted. Defaults to 1. |
tp_val |
The value of a True Positive. 'var_cost' is automatically subtracted. Either a single value or an unquoted column name (or vector). |
fp_val |
The cost of a False Positive. 'var_cost' is automatically subtracted. Either a single value or an unquoted column name (or vector). |
tn_val |
The value of a True Negative. Either a single value or an unquoted column name (or vector). |
fn_val |
The cost of a False Negative. Either a single value or an unquoted column name (or vector). |
prob_col |
The unquoted name of the column with probabilities of the event of interest. |
truth_col |
The unquoted name of the column with the actual outcome/class. |
positive |
The value in ‘truth_col' that identifies the event of interest. Defaults to ’Yes'. |
A data frame with the following columns:
threshold = prediction thresholds
payoff = calculated profit for each threshold
profit_thresholds(predictions, var_cost = 100, prob_accept = .8, tp_val = 2000, fp_val = 0, tn_val = 0, fn_val = -2000, prob_col = Yes, truth_col = Churn)profit_thresholds(predictions, var_cost = 100, prob_accept = .8, tp_val = 2000, fp_val = 0, tn_val = 0, fn_val = -2000, prob_col = Yes, truth_col = Churn)
For an *uplift* (a.k.a. treatment-effect) model, targeting the customers most likely to respond is not the same as targeting those most likely to respond *because* they were treated. The Qini curve evaluates a model that scores the predicted treatment effect using data from a treated / control experiment. Cases are ranked from highest to lowest predicted uplift and the curve shows the cumulative *incremental* number of positive outcomes attributable to treatment as more of the population is targeted.
qini_curve( x, uplift_col = NA, treatment_col = NA, outcome_col = NA, positive = "Yes", treated = 1, ci = FALSE, n_boot = 1000, conf_level = 0.95 )qini_curve( x, uplift_col = NA, treatment_col = NA, outcome_col = NA, positive = "Yes", treated = 1, ci = FALSE, n_boot = 1000, conf_level = 0.95 )
x |
A data frame with one row per case, containing the predicted uplift, the treatment indicator and the observed outcome. |
uplift_col |
The unquoted name of the column with the predicted uplift score. |
treatment_col |
The unquoted name of the treatment-indicator column. |
outcome_col |
The unquoted name of the observed-outcome column. |
positive |
The value in ‘outcome_col' that identifies the event of interest. Defaults to ’Yes'. |
treated |
The value in 'treatment_col' that identifies the treated group. Defaults to 1. |
ci |
Add bootstrap confidence bands? When 'TRUE', the returned data frame gains '.lower' and '.upper' columns and 'autoplot()' draws a ribbon. Defaults to 'FALSE'. |
n_boot |
Number of bootstrap resamples used when 'ci = TRUE'. Defaults to 1000. |
conf_level |
Width of the confidence band when 'ci = TRUE'. Defaults to 0.95. |
At the top 'k' of the ranking the incremental response is estimated as 'R_t - R_c * (N_t / N_c)', where 'R_t', 'R_c' are the positive outcomes and 'N_t', 'N_c' the counts in the treated and control groups respectively. The dashed reference line is random targeting. The area between the curve and that line (the **Qini coefficient**) and the area under the curve (**AUUC**) are attached as the attributes '"qini"' and '"auuc"'.
A data frame (class 'mi_qini') with the columns:
row = row numbers
prop_pop = proportion of the population targeted (row / n)
uplift = cumulative incremental positive outcomes
baseline = the random-targeting reference line
The Qini coefficient and AUUC are available as 'attr(result, "qini")' and 'attr(result, "auuc")'.
set.seed(1) n <- 1000 treat <- rbinom(n, 1, 0.5) u <- runif(n) y <- rbinom(n, 1, pmin(0.2 + treat * 0.5 * u, 1)) df <- data.frame(score = u, treat = treat, y = ifelse(y == 1, "Yes", "No")) q <- qini_curve(df, uplift_col = score, treatment_col = treat, outcome_col = y) attr(q, "qini")set.seed(1) n <- 1000 treat <- rbinom(n, 1, 0.5) u <- runif(n) y <- rbinom(n, 1, pmin(0.2 + treat * 0.5 * u, 1)) df <- data.frame(score = u, treat = treat, y = ifelse(y == 1, "Yes", "No")) q <- qini_curve(df, uplift_col = score, treatment_col = treat, outcome_col = y) attr(q, "qini")
Calculates the points of the ROC curve and the precision-recall curve by walking down the observations sorted by descending predicted probability. The returned data frame contains everything needed to draw both curves and to overlay an iso-profit / cost-sensitive operating point.
roc_pr(x, prob_col = NA, truth_col = NA, positive = "Yes")roc_pr(x, prob_col = NA, truth_col = NA, positive = "Yes")
x |
A data frame containing predicted probabilities of a target event and the actual outcome/class. |
prob_col |
The unquoted name of the column with probabilities of the event of interest. |
truth_col |
The unquoted name of the column with the actual outcome/class. |
positive |
The value in ‘truth_col' that identifies the event of interest. Defaults to ’Yes'. |
A data frame with the following columns:
threshold = probability at each operating point
tp = true positives when classifying every row at or above the point as positive
fp = false positives
tpr = true positive rate / recall / sensitivity (tp / all positives)
fpr = false positive rate (fp / all negatives)
precision = tp / (tp + fp)
recall = same as tpr
roc_pr(predictions, prob_col = Yes, truth_col = Churn)roc_pr(predictions, prob_col = Yes, truth_col = Churn)
Calculates ROI after sorting observations with ROI defined as (Current Value - Start Value) / Start Value
roi( x, fixed_cost = 0, var_cost = 0, tp_val = 0, prob_accept = 1, prob_col = NA, truth_col = NA, positive = "Yes", ci = FALSE, n_boot = 1000, conf_level = 0.95 )roi( x, fixed_cost = 0, var_cost = 0, tp_val = 0, prob_accept = 1, prob_col = NA, truth_col = NA, positive = "Yes", ci = FALSE, n_boot = 1000, conf_level = 0.95 )
x |
A data frame containing predicted probabilities of a target event and the actual outcome/class. |
fixed_cost |
Fixed cost (e.g. of a campaign) |
var_cost |
Variable cost (e.g. discount offered). Either a single value applied to every case, or an unquoted column name (or vector) giving a per-observation cost. |
tp_val |
The value of a True Positive. Either a single value applied to every case, or an unquoted column name (or vector) giving a per-observation value. |
prob_accept |
Probability of the offer being accepted. Variable cost is only incurred when accepted. Defaults to 1. |
prob_col |
The unquoted name of the column with probabilities of the event of interest. |
truth_col |
The unquoted name of the column with the actual outcome/class. |
positive |
The value in ‘truth_col' that identifies the event of interest. Defaults to ’Yes'. |
ci |
Add bootstrap confidence bands? When 'TRUE', the returned data frame gains '.lower' and '.upper' columns and 'autoplot()' draws a ribbon. Defaults to 'FALSE'. |
n_boot |
Number of bootstrap resamples used when 'ci = TRUE'. Defaults to 1000. |
conf_level |
Width of the confidence band when 'ci = TRUE'. Defaults to 0.95. |
A data frame with the following columns:
row = row numbers
pct = percentiles
cum_rev = cumulated revenue
cost_sum = cumulated costs
roi = return on investment
roi(predictions, fixed_cost = 1000, var_cost = 100, tp_val = 2000, prob_col = Yes, truth_col = Churn)roi(predictions, fixed_cost = 1000, var_cost = 100, tp_val = 2000, prob_col = Yes, truth_col = Churn)
Opens a small Shiny application for exploring the package interactively. You can use the bundled 'predictions' data or upload your own CSV (choosing comma or semicolon as the separator), pick the probability and outcome columns and the positive class, adjust the cost/value parameters, and watch every plot update live.
run_app(...)run_app(...)
... |
Additional arguments passed to [shiny::runApp()]. |
Requires the shiny and ggplot2 packages, which are only needed for this function.
Called for its side effect of starting the app; returns nothing.
## Not run: run_app() ## End(Not run)## Not run: run_app() ## End(Not run)
Varies each cost/value assumption up and down by a fixed fraction, one at a time, and records how the maximum achievable profit (the peak of the [profit()] curve) responds. The result feeds a tornado plot, ordering the assumptions by how much they move the bottom line.
tornado( x, fixed_cost = 0, var_cost = 0, tp_val = 0, prob_col = NA, truth_col = NA, positive = "Yes", variation = 0.2 )tornado( x, fixed_cost = 0, var_cost = 0, tp_val = 0, prob_col = NA, truth_col = NA, positive = "Yes", variation = 0.2 )
x |
A data frame containing predicted probabilities of a target event and the actual outcome/class. |
fixed_cost |
Baseline fixed cost. |
var_cost |
Baseline variable cost per targeted customer. |
tp_val |
Baseline average value of a True Positive. |
prob_col |
The unquoted name of the column with probabilities of the event of interest. |
truth_col |
The unquoted name of the column with the actual outcome/class. |
positive |
The value in ‘truth_col' that identifies the event of interest. Defaults to ’Yes'. |
variation |
Fraction by which each parameter is moved up and down. Defaults to 0.2 (+/- 20 percent). |
A data frame, one row per parameter, ordered by descending 'swing':
parameter = the assumption varied
low_value = parameter value on the low side
high_value = parameter value on the high side
low_profit = maximum profit at the low value
high_profit = maximum profit at the high value
base_profit = maximum profit at the baseline values
swing = absolute difference between low_profit and high_profit
tornado(predictions, fixed_cost = 1000, var_cost = 100, tp_val = 2000, prob_col = Yes, truth_col = Churn)tornado(predictions, fixed_cost = 1000, var_cost = 100, tp_val = 2000, prob_col = Yes, truth_col = Churn)
Translates a Qini/uplift ranking into money. Cases are ranked from highest to lowest predicted uplift and, as more are targeted, the estimated incremental positive outcomes (see [qini_curve()]) are valued at 'tp_val' and the cost of treating them is subtracted. It answers *"how many of the most persuadable cases should we treat to maximise incremental profit?"* and returns an object that plots the same way as [profit()].
uplift_profit( x, fixed_cost = 0, var_cost = 0, tp_val = 0, prob_accept = 1, uplift_col = NA, treatment_col = NA, outcome_col = NA, positive = "Yes", treated = 1, ci = FALSE, n_boot = 1000, conf_level = 0.95 )uplift_profit( x, fixed_cost = 0, var_cost = 0, tp_val = 0, prob_accept = 1, uplift_col = NA, treatment_col = NA, outcome_col = NA, positive = "Yes", treated = 1, ci = FALSE, n_boot = 1000, conf_level = 0.95 )
x |
A data frame with one row per case, containing the predicted uplift, the treatment indicator and the observed outcome. |
fixed_cost |
Fixed cost (e.g. of a campaign). |
var_cost |
Variable cost per treated case. Either a single value or an unquoted column name (or vector) giving a per-observation cost. |
tp_val |
The value of one incremental positive outcome. |
prob_accept |
Probability of the offer being accepted. Variable cost is only incurred when accepted. Defaults to 1. |
uplift_col |
The unquoted name of the column with the predicted uplift score. |
treatment_col |
The unquoted name of the treatment-indicator column. |
outcome_col |
The unquoted name of the observed-outcome column. |
positive |
The value in ‘outcome_col' that identifies the event of interest. Defaults to ’Yes'. |
treated |
The value in 'treatment_col' that identifies the treated group. Defaults to 1. |
ci |
Add bootstrap confidence bands? When 'TRUE', the returned data frame gains '.lower' and '.upper' columns and 'autoplot()' draws a ribbon. Defaults to 'FALSE'. |
n_boot |
Number of bootstrap resamples used when 'ci = TRUE'. Defaults to 1000. |
conf_level |
Width of the confidence band when 'ci = TRUE'. Defaults to 0.95. |
A data frame (class 'mi_profit') with the columns:
row = row numbers
pct = percentiles
profit = incremental profit for the number of cases targeted
set.seed(1) n <- 1000 treat <- rbinom(n, 1, 0.5) u <- runif(n) y <- rbinom(n, 1, pmin(0.2 + treat * 0.5 * u, 1)) df <- data.frame(score = u, treat = treat, y = ifelse(y == 1, "Yes", "No")) uplift_profit(df, var_cost = 1, tp_val = 100, uplift_col = score, treatment_col = treat, outcome_col = y)set.seed(1) n <- 1000 treat <- rbinom(n, 1, 0.5) u <- runif(n) y <- rbinom(n, 1, pmin(0.2 + treat * 0.5 * u, 1)) df <- data.frame(score = u, treat = treat, y = ifelse(y == 1, "Yes", "No")) uplift_profit(df, var_cost = 1, tp_val = 100, uplift_col = score, treatment_col = treat, outcome_col = y)
The gains view for a model that predicts a continuous outcome (for example predicted customer lifetime value, spend, or loss) rather than a class. Cases are ranked from highest to lowest predicted value and the curve shows what proportion of the *total realised value* is captured by targeting the top share of the population. It is the regression analogue of [cumulative_gains()].
value_gains( x, pred_col = NA, value_col = NA, ci = FALSE, n_boot = 1000, conf_level = 0.95 )value_gains( x, pred_col = NA, value_col = NA, ci = FALSE, n_boot = 1000, conf_level = 0.95 )
x |
A data frame containing a model's predicted value and the realised value. |
pred_col |
The unquoted name of the column with the model's predicted value. |
value_col |
The unquoted name of the column with the realised value. Values are assumed to be non-negative. |
ci |
Add bootstrap confidence bands? When 'TRUE', the returned data frame gains '.lower' and '.upper' columns and 'autoplot()' draws a ribbon. Defaults to 'FALSE'. |
n_boot |
Number of bootstrap resamples used when 'ci = TRUE'. Defaults to 1000. |
conf_level |
Width of the confidence band when 'ci = TRUE'. Defaults to 0.95. |
A concentration coefficient (an accuracy ratio, often called a Gini) is attached to the result as the attribute ‘"gini"'. It compares the model’s ranking to a perfect (oracle) ranking that sorts by the realised value: 1 means the model orders cases as well as an oracle, 0 means it is no better than random, and negative values mean it is worse than random.
A data frame (class 'mi_value_gains') with the columns:
row = row numbers
prop_pop = proportion of the population targeted (row / n)
cum_value = cumulated realised value captured
gain = proportion of all realised value captured
baseline = expected gain from random targeting (equal to prop_pop)
The concentration coefficient is available as 'attr(result, "gini")'.
df <- data.frame(pred = c(9, 7, 5, 3, 1), value = c(100, 80, 20, 40, 5)) vg <- value_gains(df, pred_col = pred, value_col = value) attr(vg, "gini")df <- data.frame(pred = c(9, 7, 5, 3, 1), value = c(100, 80, 20, 40, 5)) vg <- value_gains(df, pred_col = pred, value_col = value) attr(vg, "gini")
The profit view for a model that predicts a continuous outcome. Cases are ranked from highest to lowest predicted value and, as more are targeted, the realised value they bring in ('value_col') is accumulated and the cost of targeting them subtracted. It is the regression analogue of [profit()], and returns an object that plots the same way (via 'autoplot()' / [plot_profit()]).
value_profit( x, fixed_cost = 0, var_cost = 0, prob_accept = 1, pred_col = NA, value_col = NA, ci = FALSE, n_boot = 1000, conf_level = 0.95 )value_profit( x, fixed_cost = 0, var_cost = 0, prob_accept = 1, pred_col = NA, value_col = NA, ci = FALSE, n_boot = 1000, conf_level = 0.95 )
x |
A data frame containing a model's predicted value and the realised value. |
fixed_cost |
Fixed cost (e.g. of a campaign). |
var_cost |
Variable cost per targeted case. Either a single value or an unquoted column name (or vector) giving a per-observation cost. |
prob_accept |
Probability of the offer being accepted. Variable cost is only incurred when accepted. Defaults to 1. |
pred_col |
The unquoted name of the column with the model's predicted value. |
value_col |
The unquoted name of the column with the realised value. |
ci |
Add bootstrap confidence bands? When 'TRUE', the returned data frame gains '.lower' and '.upper' columns and 'autoplot()' draws a ribbon. Defaults to 'FALSE'. |
n_boot |
Number of bootstrap resamples used when 'ci = TRUE'. Defaults to 1000. |
conf_level |
Width of the confidence band when 'ci = TRUE'. Defaults to 0.95. |
A data frame (class 'mi_profit') with the columns:
row = row numbers
pct = percentiles
profit = profit for the number of rows selected
df <- data.frame(pred = c(9, 7, 5, 3, 1), value = c(100, 80, 20, 40, 5)) value_profit(df, var_cost = 10, pred_col = pred, value_col = value)df <- data.frame(pred = c(9, 7, 5, 3, 1), value = c(100, 80, 20, 40, 5)) value_profit(df, var_cost = 10, pred_col = pred, value_col = value)