r - apply a function on data n number of times

apply function to multiple data frames r
r loop through multiple data frames
apply a function to a list of dataframes in r
how to run a function multiple times in r
r apply function with multiple arguments to data frame
r loop through list of variables
r apply custom function to each row
repeat function in r

I would like to apply the same function certain number of times on a vector using the output from the function every time.

A simplified example with a simple function just to demonstrate:

# sample vector
a <- c(1,2,3)

# function to be applied n times
f1 <- function(x) {
  x^2 + x^3
 }

I would like to apply f1 on a, n number of times, for example here lets say 3 times.

I heard purrr::reduce or purrr::map() might be a good idea for this but couldn't make it work.

The desired output if n = 3 would be equal to f1(f1(f1(a))).

Then you then Split it up into many smaller datasets, Apply a function to plot(​data[[1]]$time, data[[1]]$temp, ylim=ylim, type="n", xlab="Time",  The apply () function splits up the matrix in rows. Remember that if you select a single row or column, R will, by default, simplify that to a vector. The apply () function then uses these vectors one by one as an argument to the function you specified. So, the applied function needs to be able to deal with vectors.

i <- 1

while (i < 10) {
  i <- i + 1
  x <- f(x)
}

In this tutorial we show the use of apply in R, its variants, and a few of its relatives, These functions allow crossing the data in a number of ways and avoid the function replicates its values a specified number of times. In short, mapply() applies a Function to Multiple List or multiple Vector Arguments. The apply () collection is bundled with r essential package if you install R with Anaconda. The apply () function can be feed with many functions to perform redundant application on a collection of object (data frame, list, vector, etc.). The purpose of apply () is primarily to avoid explicit uses of loop constructs.

Here is an option with accumulate

library(tidyverse)
n <- 3
a %>% 
  accumulate(~ .x %>%
                 f1, .init = f1(a)) %>%
  extract2(n)
#[1] 1.872000e+03 6.563711e+09 1.102629e+14

NOTE: accumulate is similar to the base R option Reduce with accumulate = TRUE

checking with the OP's output

f1(f1(f1(a)))
#[1] 1.872000e+03 6.563711e+09 1.102629e+14

Or use a for loop (no external libraries used)

out <- a
for(i in seq_len(n)) out <- f1(out)
out
#[1] 1.872000e+03 6.563711e+09 1.102629e+14

vapply is similar to sapply , but has a pre-specified type of return value, so it can tapply , mapply for applying a function to multiple arguments, and rapply for a  The apply () Family. The apply () family pertains to the R base package and is populated with functions to manipulate slices of data from matrices, arrays, lists and dataframes in a repetitive way. These functions allow crossing the data in a number of ways and avoid explicit use of loop constructs.

Here's another way to do it with Reduce:

setting the stage
a <- 1:3
f1 <- function(x) x^2 + x^3
constructing a call and evaluating it
N <- 3   # how many times?
r <- Reduce(function(a,b) call("f1", a), rep(NA, N), init=a)
# f1(f1(f1(1:3)))
eval(r)
# [1] 1.872000e+03 6.563711e+09 1.102629e+14
alternative 2
# N defined as above
Reduce(function(x,y) y(x), replicate(N,f1), init=a)
# [1] 1.872000e+03 6.563711e+09 1.102629e+14
alternative 3 (recursive with a global-like variable)
doit <- function(N) {
  i <- 0
  function(fun, x){
    i <<- i +1
    if(i < N) Recall(fun, fun(x)) else fun(x)
  }
}
doit(3)(f1, a)
# [1] 1.872000e+03 6.563711e+09 1.102629e+14

... or even

doit <- function(N, fun, x) (function(fun, x) 
    if((N <<- N - 1) > 0) 
      Recall(fun, fun(x)) else 
        fun(x))(fun, x)
doit(3, f1, a)
# [1] 1.872000e+03 6.563711e+09 1.102629e+14

6.0.1 Example 1: using apply to get summary data; 6.0.2 Example 2: Saving the There are so many different apply functions because they are meant to operate on different types of data. As you can see, the function correctly returned a vector of n-1 for each column. This time, the lapply function seemed to work better. The general rule for date/time data in R is to use the simplest technique possible. Thus, for date only data, as.Date will usually be the best choice. If you need to handle dates and times, without timezone information, the chron library is a good choice; the POSIX classes are especially useful when timezone manipulation is important.

allow repetition of instructions for several numbers of times. However, at large scale data processing usage of these loops can consume more  Anonymous Functions in R. When you don’t give a name to a function, you are creating an anonymous function. How is this possible? This is because in R a function (or any object, in fact) is evaluated without the need to assign it or its result to any named variable and can apply to any standard R function.

You can use lapply() to evaluate a function multiple times each with a different argument. Below, is an example where I call the runif() function (to generate  If the output of the function is a single value, then the lapply/sapply/mapply will return N values; in which case the output might be best stored in a vector. For example, mean () returns the mean of a vector of numbers — output is a single value. So running any of the apply functions will return N means. But if the output of the function is

logical; if TRUE and if X is character, use X as names for the result unless it had names already. n, number of replications. expr, expression (language object,  And here are more. How many times does each name occur? > count (bevs, "name") name freq 1 Bill 4 2 Llib 4. How many times did each person drink each drink? To say you want to tally things up by more than one column use the c function to combine things into a vector: > count (bevs, c ("name", "drink")) name drink freq 1 Bill cocoa 2 2 Bill

Comments
  • You should make your function return something.
  • @apitsch, it does, implicitly. That is, if the last line of code in the function block is x^2 + x^3, this is equivalent to both return(x^2 + x^3) and tmp <- x^2 + x^3 ; return(tmp).
  • @r2evans Thanks for letting me know. Glad to learn something new.
  • BTW: @apitsch, this can bite you: if the function does a partial assignment such as mtcars$cyl <- mycars$cyl + 1, then the value returned is not mtcars, it's mtcars$cyl, a common mistake to make. You can see that the assignment is invisibly returning the values assigned by wrapping the call in just parens, as in (on your console) (mtcars$cyl <- mycars$cyl + 1). For this reason, many (as you were suggesting) feel that explicit return(...) statements can be a good thing.
  • @r2evans return is needed only in special cases... in general case, the last expression evaluated within a function is returned. You need an explicit return statement only if you want to break out of the function and return a value before that. return does not affect the "visibility / invisibility" of the returned value: for example, assignment returns the value that was assigned but does so invisibly. Try fun <- function(x) return(a<-x) -- now fun(3)==3 equals TRUE but fun(3) does not show any value on the screen. But fun <- function(x) (a<-x) would behave differently.
  • definitely what I was looking for
  • can this be done without keeping the intermediate results. With purrr::map maybe ?
  • @adl map applies the function on each elements separately and not get the function to be applied on the output of each one recursively
  • it is in magrittr. Thank you for your answer
  • Instead of accumulate %>% extract2, couldn't you just use purrr::reduce?
  • @r2evans I understand that reduce is better in this case. I was thinking about gertting ` list` of vectors and then the OP can decide whether to select one element or multiple
  • You're capitalizing on the fact that the vector length and the number of repetitions are the same, I did not assume that from the OP.
  • Here is another way Reduce(function(a,b) get("f1")(a), a, init = a)