Search code examples
rpurrr

Understanding accumulate function when .dir is set to "backwards"


I am doing a detailed write up of purrr's accumulate function and for the most part, I understand its mechanics when the .dir is set to "forward", however when I set .dir to "backward" I am getting non-intuitive results.

Below is understanding of accumulate when .dir is set to "forward":

When using accumulate, the .x arg is passed through to your body's function via the '...'(or could be a second named argument) and the function's body's output is passed through to your function as an iterative input via a named argument (say "x")

Below is an example of how I am using only one input of purrr's function (the iterative piece and ignoring the .x as an input)

library(tidyverse)

accumulate(
  .x= 20:25 # this gets passed through to the body's function via `...`

  ,.f = function(x,...){

      print(paste0("... is: ",...))    # this will print the .x args sequentially

      print(paste0("x is: ",x))        # this will print the .init command then function's body recursive input

    

      sum(x,1)                         # this function that will start with the previous output (or .init) and iteratively repeat (ignoring .x)
    
  }
  ,.init = 0 #the initial input to iterative function
  ,.dir = "forward"
)

When running this we validate our understanding above that function starts with 0 (from .init arg of 0) and then sequentially increases by 1 and ignores the .x input (only using them in the print command)

The confusion arises when we keep the same function and change .dir to be "backward".

# comments are relative to what happens when .dir is set to forward

accumulate(
  .x= 20:25 # this gets passed through to the function via `...`

  ,.f = function(x,...){

      print(paste0("... is: ",...))    # this will print the .x args sequentially

      print(paste0("x is: ",x))        # this will print the .init command then recursive

    

      sum(x,1)                         this function that will start with the previous output (or .init) and iteratively repeat (ignoring .x)
    
  }
  ,.init = 0 #the initial input to iterative function
  ,.dir = "backward"
)

From the above, I would expect the ".x" args to be ignored and instead only the function's previous input to flow through function's body.

Instead the .x args pass through to the function body via named "x" variable and instead the "..." args is ignored (the opposite of above)

Thoughts on why the arguments switch? Is it important to understand? or from a practitioner's view can I just note the input logic switches when the .dir is set to backward?


Solution

  • After further investigation, when you set the .dir argument to "backward" it flips the order of .x and ... in your function's body.

    Everything else the same, you just have to remember to swap them.