Search code examples
rdataframefunctionwhile-loopreturn-value

How to return iteratively updated data frame from function in R?


Say I want to perform iterative calculations inside a while loop and maintain a running record, then return the dataset as follows (using proper scoping):

df <- data.frame(iter=integer(), x=integer())
x = 0

df_func <- function(df, x, num_iter){
  i = 0
  while(i < num_iter){
    i = i + 1
    x = x + 10
    new_df = data.frame(iter=i, x=x)
    df <<- rbind(df, new_df)
  }
  return(df)
}

df_func(df, x, 10)

I'd like df to contain ten rows with x=1 to 10 values, but instead I get only the last row:

> df
  iter   x
1   10 100

What am I missing?


Solution

  • To somewhat expand on MrFlick's comments:

    The issue here is that functions in R perform pass-by-value: df inside df_func is a copy of df (the data.frame with empty columns iter and x) passed to the function. This copy is never modified due to the usage of <<-. Instead, in each iteration of while

    df <<- rbind(df, new_df),

    which is equivalent to

    df <<- rbind(data.frame(iter=integer(), x=integer()), new_df),

    modifies df in the global environment, resulting in

    > df
      iter   x
    1   10 100
    

    after 10 iterations.