Relooping a function over its own output
A loop would work just fine here.
apply_fun_n_times <- function(input, fun, n){
for(i in 1:n){
input <- fun(input)
}
return(input)
}
addone <- function(x){x+1}
apply_fun_n_times(1, addone, 3)
which gives
> apply_fun_n_times(1, addone, 3)
[1] 4
Passing the output of a function back to the input multiple times
EDIT: After clarification
So, if it is some known (limited) number of times you would like to apply p
in succession, this would be one way (I have assumed some simple functions for sp
and bp
for illustration):
sp <- function(x) return(x+1)
bp <- function(x) return(2*x)
p <- function(x) return(sp(bp(x)))
# Applying p 3 times in succession:
p_old <- 1
for (i in 1:3){
p_new = p(p_old)
p_old = p_new
}
p_new
#> [1] 15
# Which is the same as
p(p(p(1)))
#> [1] 15
Created on 2020-09-11 by the reprex package (v0.3.0)
I am not quite sure what use case you have in mind (because that can easily lead to an infinite "loop", but here is one (admittedly contrived) example of a function which sums some numbers regardless in how many lists they can be nested which is using a call of the same function in the function definition itself:
sum_of_c_or_list <- function(x){
if (!is.list(x)) return(sum(x))
else {
x = unlist(x)
x = sum_of_c_or_list(x)
return(x)
}
}
sum_of_c_or_list(1:3)
#> [1] 6
sum_of_c_or_list(list(1,2,3))
#> [1] 6
sum_of_c_or_list(list(list(1,2,3)))
#> [1] 6
Created on 2020-09-11 by the reprex package (v0.3.0)
Call function on its own output, N times
Is there a simple/fast way to do this
Yes, this is a trivial loop:
N = 3
for(i in 1:N) {
data = fun(data)
}
without using slow loops?
This is not slow.
Loops in R are slower than vectorized operations. However, since each iteration depends on the previous result, this cannot be vectorized. With R's JIT compilation, a for
loop will likely be faster than common ways in R to hide loops, like *apply
functions. And anyway, it's difficult to make most of the *apply functions update their inputs for successive iterations, as is needed here. (JIT compilation has been enabled by default for many years now.)
How to rbind output of repeated function to a df - vectorized
You can use lapply()
, and do.call()
do.call(rbind, lapply(l1, f1))
Running a function repeatedly and appending its output
I am not sure if I understood you correctly. Do you want to do something like the following?
out <- lapply(X=1:10,FUN=function(x) ssa(x0, a, nu, tf=100)$data)
This would do 10 runs and put the resulting data lists in a list. You could then access,e.g., the data from the second run with out[[2]]
.
How to repeat a code for multiple times and store the output of each iteration in the same dataframe?
In the absence of a reproducible example, the following uses an example from the {Metrics}
package documentation to construct your dataframe dp
. Augment as appropriate.
Further you need to provide parameters to your function. In this case we supply the data frame dp
(which you call in your function).
Lastly, replicate()
returns an array/matrix. We reformat this into a "long" format and then coerce it to a data frame.
library(Metrics)
# simulate the data -----------------------------------------
actual <- c(1.1, 1.9, 3.0, 4.4, 5.0, 5.6)
predicted <- c(0.9, 1.8, 2.5, 4.5, 5.0, 6.2)
dp <- data.frame(
true_norm = actual
, dp_threshold_norm = predicted
)
# make function work -----------------------------------------
getValue <- function(dp) { # we define a parameter dp for the function
mae <- mae(dp$true_norm, dp$dp_threshold_norm)
rmse <- rmse(dp$true_norm, dp$dp_threshold_norm)
per_metrics <- c(mae,rmse)
return(per_metrics) # return value
}
# apply function multiple times with replicate()
# check this to understand the returned data format
replicate(n = 10, expr = getValue(dp))
# result ---------------------------------------------
## store in variable
result <- replicate(n = 10, expr = getValue(dp))
## coerce to "long data frame" - here we set ncol 2 for 2 variables
result <- matrix(result, ncol = 2)
## coerce to data frame
result <- as.data.frame.array(result)
This yields:
result
V1 V2
1 0.2500000 0.2500000
2 0.3341656 0.3341656
3 0.2500000 0.2500000
4 0.3341656 0.3341656
5 0.2500000 0.2500000
6 0.3341656 0.3341656
7 0.2500000 0.2500000
8 0.3341656 0.3341656
9 0.2500000 0.2500000
10 0.3341656 0.3341656
You can now rename the columns as required.
How can you apply a function repeatedly while updating the input
Use Reduce:
test_df %>% Reduce(function(...) separate_rows(..., sep = "_"), 2:3, init = .)
giving:
# A tibble: 26 x 3
x y z
<dbl> <chr> <chr>
1 1 10 1
2 1 10 2
3 1 10 3
4 1 10 4
5 1 10 5
6 1 11 1
7 1 11 2
8 1 11 3
9 1 11 4
10 1 11 5
# ... with 16 more rows
reduce
from purrr also works (switch the first two args and use .init rather than init for that) but has no real advantage here.
How to pass the output of a function to another function in R?
There are quite a few things going on here, and it really partly depends on if you are showing us a very simplified version. For example, are you really doing the same thing to x, y, z in the first function or are you possibly doing different things?
First, the i
, j
and k
vectors that you are creating in func1() do not exist outside of func1().
As @akrun said you could rectify this bye making them into a vector (if they are always of the same type) or a list and then returning that.
So then you could get, say,
func1 <- function(x, y, z) {
k <- x*2
j <- y*2
i <- z*2
c(k, j, i)
}
At which point you could a a parameter to your second function.
func2 <- function(x, y, z) {
ijk <- func1(x, y, z)
prod(ijk)
}
Of course even easier if you can vectorize func1() (but I don't know how much you simplified).
func1v2 <- function(x, y, z) {
2* c(k, j, i)
}
Related Topics
How to Read Column Names 'As Is' from CSV File
Align Points and Error Bars in Ggplot When Using 'Jitterdodge'
How to Sort a Vector of Alphanumeric Values Using Lexical Ordering in R
Parallel R on a Windows Cluster
Get Rows of Unique Values by Group
Is There a Package or Technique Availabe for Calculating Large Factorials in R
Get Most Frequent String from a Data Frame Column
Terms of a Sum in a R Expression
Predict.Lm in R Fails to Recognize Newdata
What Is the Equivalent of Mutate_At (Dplyr) in Data.Table
Calculating the Distance Between Points in Different Data Frames
R: Ggplot2 Setting the Last Plot in the Midle with Facet_Wrap
How to Create a Single Dummy Variable with Conditions in Multiple Columns
Choose Specific Number with Probability