yardstick recall() in R: Score True Positive Rate
The yardstick recall() function in R returns the share of actual positives the classifier caught, accepting a tibble of truth and prediction columns and returning a tidy one-row summary you can group, average across classes, or combine with precision in a metric set.
recall(df, truth, estimate) # basic two-class call recall(df, truth = obs, estimate = pred) # named arguments recall(df, class, .pred_class) # default parsnip output df |> group_by(fold) |> recall(class, .pred_class) # by resample recall(df, class, .pred_class, estimator = "macro") # multiclass macro average recall(df, class, .pred_class, event_level = "second") # flip positive class recall_vec(truth_vec, pred_vec) # vector interface
Need explanation? Read on for examples and pitfalls.
What recall() measures
recall() answers a single question: of every real positive case, how many did the model catch? You pass a data frame with observed and predicted labels, and the function returns a one-row tibble with .metric, .estimator, and .estimate. The estimate is true positives over the sum of true positives and false negatives, a number between 0 and 1.
Recall is the headline metric whenever missing a positive is expensive. Cancer screening, fraud detection on rare events, and churn warnings all share the shape where a missed positive costs more than a noisy alert. Accuracy hides that asymmetry; recall exposes it directly.
precision() or f_meas().recall() syntax and arguments
The signature follows the rest of the yardstick class-metric family. The same call shape works for any classifier whose predictions land in a tibble.
| Argument | Description |
|---|---|
data |
A data frame with truth and estimate columns. |
truth |
Unquoted column name of the observed class labels (a factor). |
estimate |
Unquoted column name of the predicted class labels (a factor with matching levels). |
estimator |
Averaging mode for multiclass: "binary", "macro", "macro_weighted", or "micro". Defaults to "binary" for two-class data and "macro" for multiclass. |
na_rm |
If TRUE, drop rows where either column is missing before scoring. |
event_level |
"first" or "second"; controls which factor level counts as the positive class. |
Both truth and estimate must be factors with identical levels. The most common slip is passing class probabilities; recall needs class labels, so feed .pred_class from parsnip::augment(), not a .pred_<level> column.
Score classifiers: four worked examples
The examples below build a two-class frame and a multiclass frame so you can run recall() against both shapes. Start with a small two-class tibble that mimics a cancer screening dataset.
Example 1 calls recall() with positional arguments. Because "disease" is the first factor level, yardstick treats it as the positive class.
A 0.317 recall means the model caught 32 percent of real disease cases. That miss rate is the first number a clinician will challenge.
Example 2 flips the positive class with event_level. Setting event_level = "second" makes "healthy" the positive class.
Recall on the healthy class is higher because the model predicts healthy more often. Always state which class is positive when you report the number.
Example 3 groups scoring by resample fold. Cross-validated predictions in a single tibble pair with group_by() to give one recall per fold without writing a loop.
Example 4 uses the vector interface for ad-hoc checks. recall_vec() accepts two factors and returns a plain numeric scalar, convenient inside summarise() or a quick diagnostic.
metric_set(recall, precision, f_meas) builds a reusable function you pipe predictions into to get all three scores, the minimum honest report for an imbalanced classifier.Multiclass averaging: macro, weighted, and micro
recall() handles multiclass data, but the answer depends on the averaging rule.
Scoring under each averaging mode gives a useful comparison:
| Estimator | What it does | When to use |
|---|---|---|
macro |
Unweighted mean of per-class recall | Treat every class as equally important, regardless of size |
macro_weighted |
Mean weighted by class prevalence in truth | Reflect the class mix in the real population |
micro |
Pool all predictions, then compute one ratio | Match the global hit rate; equals accuracy for symmetric metrics |
binary |
Score one positive class only | Two-class problems, set by default |
Class-imbalanced papers report macro recall because the rare class counts as much as the common one. Production dashboards prefer macro_weighted to track real traffic prevalence.
recall vs precision vs sensitivity
Three names show up around the recall column, and two of them are the same number. The table below sorts out the overlap.
| Function | What it scores | Same as |
|---|---|---|
recall() |
True positives over actual positives | Sensitivity, true positive rate |
sens() |
True positives over actual positives | recall (yardstick aliases them) |
precision() |
True positives over predicted positives | Positive predictive value |
spec() |
True negatives over actual negatives | Specificity, true negative rate |
f_meas() |
Harmonic mean of precision and recall | F1 score |
bal_accuracy() |
Mean of recall and specificity | Balanced accuracy |
recall() and sens() return identical numbers. Both honor the same event_level argument and both ship with vector cousins (recall_vec(), sens_vec()). Use recall in ML reports, sens in clinical reports, and your readers will not have to translate.
yardstick::recall() is the equivalent of sklearn.metrics.recall_score(). The estimator argument maps directly to scikit-learn's average parameter: "macro", "micro", and "macro_weighted" line up with average="macro", "micro", and "weighted".Common pitfalls
Three small mistakes account for most recall() errors.
The first is reporting high recall without checking the prediction mix. A model that labels every row positive scores 1.0 recall and zero precision; the score looks great but means the classifier is useless. Always pair recall with precision before claiming progress.
The second is forgetting to set event_level when the rare class is the second factor level. The order of levels() decides which class is positive, and a flipped order can quietly invert the metric. Confirm with levels(screening$truth) before scoring.
The third pitfall is divide-by-zero on multiclass macro averaging. If a class has zero positives in the test set, that class contributes NaN and the macro average drops to NaN. Switch to estimator = "macro_weighted" so empty classes drop out by weight, or stratify the resample.
Try it yourself
Try it: Use the built-in two_class_example data from yardstick. Compute the recall score with the default positive class, then compute it again with the positive class flipped via event_level = "second". Save the second result to ex_recall_alt.
Click to reveal solution
Explanation: event_level = "second" treats Class2 as the positive class, so recall now measures how many actual Class2 cases the model caught. The default "first" would have scored Class1 recovery instead.
Related yardstick metrics
recall() is one entry in the yardstick class-metric family. Reach for these when recall alone is not enough:
precision()for predicted-positive correctnessf_meas()for the harmonic mean of precision and recallsens()for the clinical alias of recallspec()for the negative-class catch ratebal_accuracy()averages recall and specificity, robust to imbalanceroc_auc()for threshold-free probability rankingsconf_mat()to see the full confusion matrix
For the full set, see the yardstick reference index.
FAQ
Is recall() the same as sensitivity in yardstick?
Yes, the two functions return identical numbers. yardstick::recall() and yardstick::sens() both compute true positives over actual positives, expose the same event_level and estimator arguments, and ship with vector cousins (recall_vec() and sens_vec()). The two names exist because the machine-learning literature settled on "recall" while the medical literature settled on "sensitivity." Pick whichever your audience knows.
Why does recall() return a tibble instead of a number?
The tidy return shape is the defining yardstick convention. Every metric returns the same three columns: .metric, .estimator, and .estimate. That uniformity lets you bind_rows() multiple metric calls or chain group_by() |> metric() without reshape code. For the scalar, call recall_vec() instead.
How is recall different from accuracy?
accuracy() asks how many of all predictions were correct. recall() asks how many of the actual positives were caught, ignoring the negative class entirely. On imbalanced data they diverge: a model that always predicts the majority class can hit 95 percent accuracy while scoring near-zero recall on the rare class. Report both whenever missing positives is costly.
Why does recall return NaN on my multiclass data?
A NaN recall means the test set contains zero true cases of at least one class, so the per-class recall divides by zero. Switch to estimator = "macro_weighted" to drop empty classes by weight, or stratify your resample so every class is represented before re-running the metric.