I have a loop within a function. Every repetition of the loop creates a dataframe with 100 rows and 8 columns. I want every such dataframe to be saved as a list item in a list, where the name of that list item corresponds to the name of x[i] in the function, where those names are "Var1", "Var2", "Var3".
However, for every loop my list item is just overwritten.
Func <- function(List, x){
List <- list()
{Loop that creates a data frame "df"}
List[[x[i]]] <- df
}
Output <-
Func(
Dataframe,
c(
"Var1",
"Var2",
"Var3",
)
)
Any ideas appreciated!
Edit:
Another possibility would be to simply have the dataframes named differently within the loop, something I also dont know how to achieve. For example:
Func <- function(List, x){
{loop that creates df_with_new_name_for_each_iteration}
for loops are powerful, but need some finesse, there are arguable 'easier' approaches; such as using functional tools for example lapply, to repeatedly call afunction and have the results be in a list.
This code shows a simple function that makes a data.frame myfunc
lapply is used so as to construct a list from every result of applying myfunc on the elements of to_do, and naming each such result list with a name from names_want
This is the classic trap that users coming from a background in C or one of its descendants: there is a difference between what happens within a function (in the .Local environment and what happens in the .Global environment. What happens in Las Vegas stays in Las Vegas. The return from a function includes only the results maintained at the time the function exits. That accounts for the final element only being returned.
The pattern to address this is to create a receiver object in the .Global environment. If it is going to hold a lot, be sure to initialize it to the expected size. Then within the .Local environment, each loop writes to that.
v <- vector(length = length(object))
for(i in seq_along(object)) v[i] = sqrt(i)
But the vectorized method that @nirgrahamuk suggests is generally preferable.