Search code examples
rfunctionfor-loopmontecarlo

For loops for nested variables within function in R


I would like to iterate through vectors of values and calculate something for every value while being within a function environment in R. For example:

# I have costs for 3 companies
c <- c(10, 20, 30)
# I have the same revenue across all 3 
r <- 100
#  I want to obtain the profits for all 3 within one variable
result <- list()

# I could do this in a for loop
for(i in 1:3){
    result[i] <- r - c[i]
}

Now lets assume I have a model that is very long and I define everything as a function which is to be solved with various random draws for the costs.

# Random draws
n  <- 1000
r  <- rnorm(n, mean = 100,  sd = 10)
c1 <- rnorm(n, mean = 10,  sd = 1)
c2 <- rnorm(n, mean = 20,  sd = 2)
c3 <- rnorm(n, mean = 30,  sd = 3)
X  <- data.frame(r, c1, c2, c3)

fun <- function(x){
       r  <- x[1]
       c  <- c(x[2], x[3], x[4])

       for(i in 1:3){
           result[i] <- r - c[i]
       }
  return(result)
}

I could then evaluate the result for all draws by iterating through the rows of randomly sampled input data.

for(j in 1:n){
  x <- X[j,]
  y <- fun(x)
}

In this example, the output variable y would entail the nested result variable which comprises of the results for all 3 companies. However, my line of thinking results in an error and I think it has to do with the fact that I try to return a nested variable? Hence my question how you guys would approach something like this.


Solution

  • I would suggest rethinking your coding approach. This is a very un-R-like way of doing things.

    For example, the first for loop can be written much more succinctly as

    x <- c(10, 20, 30)
    r <- 100
    result <- lapply(-x, `+`, r)
    

    Then fun becomes something like

    fun <- function(x) lapply(-x[-1], `+`, x[1])
    

    To then operate over the rows of a data.frame (which is what you seem to do in the last step), you can use something like

    apply(X, 1, fun)
    

    where the MARGIN = 1 argument in apply ensures that you are applying a function per row (as opposed to per column).