Using Dataframe to Automatically create a list of values based off Subproduct

Viewed 66
df <- data.frame("date"= 
1:4,"product"=c("B","B","A","A"),"subproduct"=c("1","2","x","y"),"actuals"=1:4)


#creates df1,df2,dfx,dfy
for(i in unique(df$subproduct)) {
  nam <- paste("df", i, sep = ".")
  assign(nam, df[df$subproduct==i,])

}

# CREATES LIST OF DATAFRAMES
# How do I make this so i don't have to manually type list(df.,df.,df.)

list_df <- list(df.1,df.2,df.x,df.y) %>%
  lapply( function(x) x[(names(x) %in% c("date", "actuals"))])

# creates df1,df2,df3,df4 only dates and actuals, removes the other column names
for (i in 1:length(list_df)) {
  assign(paste0("df", i), as.data.frame(list_df[[i]]))
}

For the first for loop, it creates a df object based off unique subproduct. For the list() function, I want to be able to not have to type in df.1 ... df2... etc so if I have 100 unique subproducts in my data, I wouldn't need to type this df.1, df.2,df.x,df.y,df.z,df.zzz,df. over and over again. How would I best do this (1 question)

The last for loop creates separate dataframe objects with only date and actuals will be used to create time series for each. How can I put the values of these objects into a single dataframe or a list of dfs? (2nd question)

1 Answers

We can use mget to return the value of object on the subset of object names from ls. The pattern matches object names that starts with 'df'followed by a.` and any alphanumeric characters

mget(ls(pattern = '^df\\.[[:alnum:]]+$'))

If the OP wanted to create those objects in a different env

new_env <- new.env()
list2env(mget(ls(pattern = '^df\\.[[:alnum:]]+$')), envir = new_env)

If we want to create new objects from scratch, do a group_split on the 'subproduct' column, set the names accordingly, and create multiple objects (list2env - not recommended though)

library(dplyr)
library(stringr)
df %>% 
   group_split(subproduct) %>%
   setNames(str_c('df.', c(1, 2, 'x', 'y'))) %>% 
   list2env(.GlobalEnv)
Related