'Dynamically assign values to named list using for loop

This post is an extension of a previous post for which the answer provided was perfectly suitable. However, I'd like to make the app more flexible by assigning the list item names dynamically, using the values in unique(iris$Species) instead of hard coding the items in the named list. I've tried to do this by assigning the items in the named list via a for loop: for (m in species_list){ paste0("species_",m) = species_table[[m]]}. However, when I run the app I get a error saying "subscript out of bounds". I've included the complete replicable example below:

data(iris)

ui <- fluidPage(
  
  mainPanel(
    fluidRow(selectInput("portfolio", label = "Select Species", choices = unique(iris$Species))),
    fluidRow(tableOutput("result"))
  )
  
)

server <- function(input, output) {
  
  species_list <- unique(iris$Species)
  
  species_function <- reactive({
    
    species_table <- list()
    for (i in reactiveValuesToList(species_list)){
      local({
        j <- i
        species_table[[j]] <<- iris[iris$Species==j,]
      })
    }
    
    return(list(
      
      for (m in species_list){
        paste0("species_",m) = species_table[[m]]      
      }
      
    ))
    
  })
  
  output$result <- renderTable({
    input$portfolio
    species_table2 <- list()
    
    for (p in reactiveValuesToList(species_list)){
      local({
        q <- p
        species_table2[[reactive({q})()]] <<- species_function()[[paste0("species_",reactive({q})())]][1:5, c("Sepal.Length", "Sepal.Width")]
      })
    }
    
    print(species_table2[[input$portfolio]])
    return(species_table2[[input$portfolio]])
    
  })
  
}

shinyApp(ui = ui, server = server)```


Solution 1:[1]

The following modified code, incorporating feedback from @MrFlick and specifying species_list as a reactive value, functions as expected.

library(shiny)
data(iris)


ui <- fluidPage(
  
  mainPanel(
    fluidRow(selectInput("portfolio", label = "Select Species", choices = unique(iris$Species))),
    fluidRow(tableOutput("result"))
  )
  
)

server <- function(input, output) {
  
  species_names <- as.character(unique(iris$Species))
  species_list <- reactiveValues()
  
  for(i in 1:length(species_names)) {
    
    species_list[[paste0("species_", i)]] <- species_names[[i]]
    
  }
  
  species_function <- reactive({
    
    species_table <- list()
    for (i in reactiveValuesToList(species_list)){
      local({
        j <- i
        species_table[[j]] <<- iris[iris$Species==j,]
      })
    }
    
    setNames(species_table, species_names)
    
  })
  
  output$result <- renderTable({
    input$portfolio
    species_table2 <- list()
    
    for (p in reactiveValuesToList(species_list)){
      local({
        q <- p
        species_table2[[reactive({q})()]] <<- species_function()[[reactive({q})()]][1:5, c("Sepal.Length", "Sepal.Width")]
      })
    }
    
    return(species_table2[[input$portfolio]])
    
  })
  
}

shinyApp(ui = ui, server = server)

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 lrclark