0

I am asking two questions:

  1. How to run a code for multiple times?
  2. How to store the output of each iteration in the same dataframe?

I have 3 outputs in my code: mae,rmse and per_metrics. I only want per_metrics for my final output for every iteration, and store the results from each per_metics for my overall output out of all the iterations.

    getValue <- 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(i)
    }
result <- replicate(10, getValue())

N.B. Number of iterations = 10

This is only part of my code, I have the same input for all iterations but a noise adding mechanism rlaplace() between the input and output. So I get a different result in every iteration.

  • 1
    Look at the documentation of `replicate`, `sapply` and `lapply`. – Roman Luštrik Aug 22 '21 at 17:02
  • To complement Roman, check your function and use of `{modelr}`. `mae()`and `rmse()` expect a model and data. The documentation shows an example. If you want to run your `getValue()` function with the same inputs, you will be generating the same results. The `per_metrics` (return) variable is currently a vector, i.e. constructed with c(). Thus, think about coding this already as a data frame. It is not considered best practice to "grow" data frames as R memory management being a bit impolite. But for 10 iterations it will work. Please note that you loop thus, result[i,] <- return-from-loop. – Ray Aug 22 '21 at 17:14
  • @Ray, probably OP is using Metrics package – Onyambu Aug 22 '21 at 17:29
  • In eirther case, your function will return THE SAME results whatever the circumstate, unless the input are altered. – Onyambu Aug 22 '21 at 17:29
  • I have the same input for every iteration but I am adding random noise every time so I get different results so as different MAE and RMSE. – SssssssAaaaaaa Aug 22 '21 at 18:21

1 Answers1

1

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.

Ray
  • 2,008
  • 14
  • 21
  • If my input changes in every iteration, does this mean I should include the `dp` inside `function(dp) {}` along with the parameters, and remain the same for the rest of your suggested code? – SssssssAaaaaaa Aug 22 '21 at 20:46
  • Apologies, took a while to come back. The idea of a function is to perform an operation. Thus, in general `input --> function --> output`. It is difficult to judge from your example how/what changes with every iteration. But conceptually, I would say yes. You could of course only provide the parameters (objects, e.g. vectors, values) that change/are relevant. Good luck with it! – Ray Aug 28 '21 at 14:40