Skip to contents

whence_trace() takes a pipeline that ends in a single value, and runs it one step at a time. It records the number of rows after each step. The result tells you how many rows each step removed, and gives code that makes the value again.

Usage

whence_trace(expr, env = parent.frame())

Arguments

expr

A pipeline that ends in a single value: a vector of length one, or a data frame with one row and one column.

env

The environment in which to evaluate expr.

Value

A whence_trace object. Use whence_value(), whence_code(), whence_rows(), as.data.frame() and print() with it.

The object is a list. These fields are stable, and you can read them:

  • value: the value, as whence_value() gives it.

  • code: the reproduce code, as whence_code() gives it.

  • traced: TRUE when the pipeline was split into steps.

  • stages: a data frame with one row for each step, as as.data.frame() gives it.

  • reason: why the chain stopped short, as one sentence, or NULL when every step was traced.

Do not rely on the other fields. They can change in any version.

Details

The pipeline is split by its verbs. A call to a known verb, such as filter() or summarise(), is a step, and its first argument is the data that comes from upstream. This works the same for the native pipe |>, for the magrittr pipe %>% and for nested calls. The chain stops at the first call that is not a known verb, such as a join. That call and all that is upstream of it become the source.

Each step is evaluated in env, as the full expression would be. A step thus sees the same variables, and in 'shiny' it reads the same inputs and reactive values.

The steps run once, in order. This is the same work as running the expression in one piece.

Limits

  • A database-backed pipeline (a tbl_lazy from 'dbplyr') is an error. Its steps run as SQL only at collect(), so there are no row counts to show.

  • Joins are not traced. A join ends the chain.

  • The verbs of 'data.table', 'arrow' and 'duckplyr' are not known.

  • The native-pipe placeholder _ is not supported. A pipeline that uses it is not split, and the value is still given.

Known verbs

These calls are steps: filter(), mutate(), transmute(), select(), rename(), arrange(), slice(), slice_head(), slice_tail(), slice_min(), slice_max(), slice_sample(), group_by(), ungroup(), summarise(), summarize(), count(), tally(), distinct(), drop_na(), pivot_longer(), pivot_wider(), pull(), head() and tail(), with or without a namespace such as dplyr::. Any other call ends the chain, and the trace says where in its reason.

Examples

library(dplyr, warn.conflicts = FALSE)

trace <- whence_trace(
  mtcars |>
    filter(cyl == 4) |>
    filter(mpg > 25) |>
    summarise(mean_hp = mean(hp))
)
trace
#> <whence_trace> 75.5
#> 
#> Where the rows went
#>   0 mtcars                  32
#>   1 -> cyl == 4             11  -21 rows (66%)
#>   2 -> mpg > 25              6  -5 rows (45%)
#>   3 -> aggregated to 1 row   1
#> 
#> Reproduce
#>   mtcars |>
#>     filter(cyl == 4) |>
#>     filter(mpg > 25) |>
#>     summarise(mean_hp = mean(hp))
as.data.frame(trace)
#>   step               label  n delta   percent      kind      verb groups shown
#> 1    0              mtcars 32    NA        NA    source      <NA>     NA  TRUE
#> 2    1            cyl == 4 11   -21 -65.62500    filter    filter     NA  TRUE
#> 3    2            mpg > 25  6    -5 -45.45455    filter    filter     NA  TRUE
#> 4    3 aggregated to 1 row  1    NA        NA summarise summarise     NA  TRUE