PAlvarez
PAlvarez

Reputation: 13

Creating a Data frame from a for loop in R

I am trying to create a Data Frame out of a For loop, how ever in all the recommendations I have found, I only get the last value of the loop and not the whole result.

I have tried creating an empty list before the loop, an empty data.frame, matrix and in the loop defined such element and after the loop again call it, but it only takes the last value of the loop.

random_growth <- rnorm(n=10000, mean=0.11, sd=0.3560766)
fcf0 <- 3619
 for (i in random_growth){
  fcf1= fcf0 *(1+i)
  fcf2= fcf1*(1+i)
  fcf3= fcf2*(1+i)
  fcf4= fcf3*(1+i)
  fcf5= fcf4*(1+i)
  fcf6= fcf5*(1+i)
  ffcfs = c(fcf1,fcf2,fcf3,fcf4,fcf5,fcf6)
  print(rbind(ffcfs))
    }

I would like to have a data frame of 6 columns and 10.000 rows. I know my loop is not the best way of doing such calculation, but I didn't find another way. Please, I would be really glad if you could help me.

I found a way to creating the data frame, but I tried to create inside the loop different if-else statements, as some values on the random_growth can be negative and it would not be applied if I do the straight formula. So I came up with this change but somehow the calculations are wrong:

random_growth <- rnorm(n=10000, mean=0.11, sd=0.3560766)
fcf0 <- 3619
ffcfs <- data.frame()
  for (i in random_growth){
    if (i>0){
  fcf1= fcf0*(1+i)
  fcf2= fcf1*(1+i)
  fcf3= fcf2*(1+i)
  fcf4= fcf3*(1+i)
  fcf5= fcf4*(1+i)
  fcf6= fcf5*(1+i)
    }
  else{
  fcf1= if ((fcf0*i)>0){fcf0*(1+i)} else {fcf0-(fcf0*i)}
  fcf2= if ((fcf1*i)>0){fcf1*(1+i)} else {fcf1-(fcf1*i)}
  fcf3= if ((fcf2*i)>0){fcf2*(1+i)} else {fcf2-(fcf2*i)}
  fcf4= if ((fcf3*i)>0){fcf3*(1+i)} else {fcf3-(fcf3*i)}
  fcf5= if ((fcf4*i)>0){fcf4*(1+i)} else {fcf4-(fcf4*i)}
  fcf6= if ((fcf5*i)>0){fcf5*(1+i)} else {fcf5-(fcf5*i)}
  }
  row_i = c(fcf1,fcf2,fcf3,fcf4,fcf5,fcf6)
  ffcfs = rbind(ffcfs,row_i)
    }

Could you help me to identify what is wrong?? Thank you very much!!

Upvotes: 0

Views: 136

Answers (2)

Shree
Shree

Reputation: 11150

A loop is not necessary for this. Here's a succinct way using lapply -

set.seed(2)
random_growth <- rnorm(n=10000, mean=0.11, sd=0.3560766)

df <- data.frame(
  setNames(
    lapply(1:6, function(x) {
      3619*(1 + random_growth)^x
    }),
    c("fcf1","fcf2","fcf3","fcf4","fcf5","fcf6")
  )
)

head(df)

      fcf1      fcf2      fcf3       fcf4       fcf5       fcf6
1 2861.289  2262.220  1788.578  1414.1033  1118.0321   883.9494
2 4255.294  5003.462  5883.173  6917.5554  8133.8033  9563.8924
3 6063.253 10158.341 17019.229 28513.9244 47772.0740 80037.0733
4 2560.441  1811.511  1281.644   906.7625   641.5342   453.8852
5 3913.674  4232.342  4576.957  4949.6326  5352.6526  5788.4882
6 4187.732  4845.842  5607.374  6488.5831  7508.2754  8688.2141

Upvotes: 0

Peer Christensen
Peer Christensen

Reputation: 104

The loop you're running keeps declaring, or updating, the ffcfs vector.

Try this instead:

random_growth <- rnorm(n=10000, mean=0.11, sd=0.3560766)
fcf0 <- 3619
ffcfs = data.frame()

for (i in random_growth){
  fcf1 = fcf0 *(1+i)
  fcf2 = fcf1*(1+i)
  fcf3 = fcf2*(1+i)
  fcf4= fcf3*(1+i)
  fcf5 = fcf4*(1+i)
  fcf6 = fcf5*(1+i)

  row_i = c(fcf1,fcf2,fcf3,fcf4,fcf5,fcf6)

  ffcfs = rbind(ffcfs,row_i)

}

This way, the ith row is added to your data frame without creating a new data frame for each iteration. Hope it helps!

Upvotes: 1

Related Questions