rfunctioncustom-function

Create an R function which dinamycally and sequentially applies other predefined functions to an initial input variable


I have a very simple set of functions which take an input character variable (a word or phrase) and return a new one. Basically, each of these functions performs a different encryption on the input word.

As both the input and the output of these functions is a character variable, the output of a function can be used as the input for another one, so that several sequential ciphers could be applied. For example:

#install.packages("ciphertext")
library(ciphertext)

first_output <- ciphertext::caesar("hello"); first_output

[1] "ifmmp"

ciphertext::atbash(first_output)

[1] "runnk"

I was wondering if there is the possibility in R to create a function (which I named combinef below) which takes in input an initial character variable ("hello", in my example) and applies sequentially other functions listed as additional arguments.

So the algorithm would be something like:

  1. Take initial word ("hello")
  2. Apply the first listed function to the initial word and obtain a new word
  3. repeat step 1 with the new word until using all the arguments listed

How I would like it to work, and the expected final output:

combinef("hello", caesar, atbash) #apply caesar function to "hello", and then atbash
[1] "runnk"


combinef("hello", caesar, atbash, polybius) #apply polybius after the atbash
"42 45 33 33 25"

All my attempts to create such a function are extremely verbose as I tried to make use of if (argument2 == "function_name") structures, but this came to be impracticable when the number of potential ciphering methods increased.

Any help or suggestion would be greatly appreciated!


Solution

  • Here is a base R approach with Reduce(), which uses a binary function to successively combine the elements of a given vector and a possibly given initial value:

    combinef <- function(init, ...) {
        Reduce(
            \(x, y) y(x), list(...),
            init = init
        )
    }
    
    combinef("hello", caesar, atbash)
    # [1] "runnk"
    

    Alternatively, you could use purrr::compose(), which crease a new function that is the composition of multiple functions:

    combinef2 <- purrr::compose(atbash, caesar)
    combinef2("hello")
    # [1] "runnk"