0

I am using two for loops to run some simulations. One that increases N by 50 each iteration and other within that runs the simulation a 1000 times. However with what I have currently the result dataframe doesn't save the outputs for each different sequence value of N and instead only shows the final output values for the last value of N in the sequence, in this case the values for N=500.

So I was wondering is there a way to make a dataframe that keeps all the output values for all the different values of N?

for (N in seq(100,500,50)) {
  P <- rep(NA,1000)
  for (i in 1:1000) {
    P[i] <- function()
  }
  result <- data.frame(P) # this is simplified 
}
digEmAll
  • 56,430
  • 9
  • 115
  • 140
SamFenton
  • 25
  • 6
  • Possibly related: https://stackoverflow.com/questions/9689387/loop-in-r-how-to-save-the-outputs – MrFlick Mar 15 '18 at 15:36
  • Initialize the `data.frame` and fill it in the loop. – cdeterman Mar 15 '18 at 15:41
  • Sorry when you say initialise the data.frame do you mean i should create a blank data frame outside the for loops and then fill it with the iteration results? – SamFenton Mar 15 '18 at 15:53
  • Assuming the output of `function()` is a data.frame, you can store each output in in `P` as a list, but you need to initialize `P` outside of the loop ` P <- list()`. Your `for` loop will then make 1000 entries in `P`, one for each output `f(i)`. – Mako212 Mar 15 '18 at 16:13
  • @Mako212 So here function() is actually the pchisq() function. So the end result of each of the 1000 runs is p value which I then make into the result dataframe. Would making a list like you suggest still work for that? – SamFenton Mar 15 '18 at 16:21
  • That would work fine. Basically you would do what I describe above, and then run `do.call(rbind, P)` which will take your list and collapse it into a single `data.frame`. More directly though, you could just initialize the empty `data.frame` as `P <- data.frame(PValue = numeric())` and then append directly as `P[i, ] <- function()`- this works nicely because you only have a single value for each output of `f(i)` – Mako212 Mar 15 '18 at 16:28

1 Answers1

0

To store values from a loop, you first need to initialize your object, then you can add values one at a time by specifying the index.

# create an empty data frame
P <- data.frame(PValue = numeric(), NValue=numeric())
P2 <- list()    

for (N in 1:10){
  for (i in 1:10){
    P[i, 1] <- pchisq(i, df=3)
    P[i, 2] <- N
  }
  # store each output from the inner loop in a list
  P2[[N]] <- P
}
# collapse the list down to a single data frame
final <- do.call(rbind, P2)
Mako212
  • 6,787
  • 1
  • 18
  • 37
  • Sorry but that doesn't solve my issue. I still only end up with the P values for the last value of N in the sequence rather than values for all values of N. – SamFenton Mar 15 '18 at 16:45
  • @SamFenton see my edit, I think you need to assign the output of your first `for` loop to a second list. – Mako212 Mar 15 '18 at 16:54
  • Yes this works to give me P values for all the different N inputs. Do you know a way I can easily input the N value for each P value into the final data.frame? – SamFenton Mar 15 '18 at 17:14
  • @SamFenton there's a few answers [here](https://stackoverflow.com/questions/15162197/combine-rbind-data-frames-and-create-column-with-name-of-original-data-frames) on how to do it programmatically. In this case, you can also just do `final$N_Value <- rep(seq(100,500,50), each=1000)` because you'll have 1000 values for each N. – Mako212 Mar 15 '18 at 17:23
  • @SamFenton actually there's a better solution I just added to my answer. We add the column indices to the inner `for` loop and then just add N to each row with `P[i, 2] <- N` – Mako212 Mar 15 '18 at 17:26