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?
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.