Put dataframe into a list within a loop

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.

consider this example


myfunc <- function(x){
  data.frame(
    x=x,
    y=x^3
  )
}
(to_do <- 1:3)
(names_want <- paste0("my_name_",to_do))

(a_list <- lapply(to_do,
       myfunc) |> setNames(names_want))

str(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

1 Like

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.

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.