变量没有被传递到传单循环来生成地图

问题描述 投票:0回答:1

我正在开发 R Shiny 应用程序。用户上传他的数据文件,它会创建中值的传单地图。困难在于我需要为每个变量生成映射,但每个文件之间的数字可能不同。

数据是反应式科幻小标题,因此提供reprex将会很困难。

问题是只有最后一个变量被多次生成。

服务器.R

# server.R

function(input, output, session){

  # Genrate fluidRow boxes for the maps
  output$all_cartes_nutri_dept <- renderUI({
    req(bilans_nutriments$dept())
    
    # Init a "table" for the maps
    tableau_cartes <- list()
    
    # nutriments to check for validity
    nutriments_mesures_to_check <- paste0(colonnes_disponibles$nutriments, "_med")
    
    # Init of valid nutriments and map names
    nutriments_valides <- c()
    noms_cartes_nutri_dept <- c()
    
    # Loop over each valid nutriment and prepare the output box
    for (i in seq_along(nutriments_mesures_to_check)) {
      
      # Verifier si la colonne est valide dans bilans_nutriments
      if (check_colonne(nutriments_mesures_to_check[i], bilan_nutri_dept_shape())) {
        
        # Add valid nutriment and map names to their respectives vectors
        nutriments_valides <- c(nutriments_valides, colonnes_disponibles$nutriments[i])
        noms_cartes_nutri_dept <- c(noms_cartes_nutri_dept, paste0("carte_nutri_dept_", colonnes_disponibles$nutriments[i]))
        
        # Add valid map box to the table of maps
        tableau_cartes[[length(tableau_cartes) + 1]] <- box(
          withSpinner(leafletOutput(noms_cartes_nutri_dept[i]), color = spinner_color)
          )
      } else {
        message_nodata <- paste("No data for nutriment:", nutriments_mesures_to_check[i])
        print(message_nodata)
      }
    }
    
    print("Nutriments valides :")
    print(nutriments_valides)
    print("Noms des cartes :")
    print(noms_cartes_nutri_dept)
    
    output$message_nodata <- renderText({
      message_nodata
      })
    
    # Créer les cases du tableau avec les boîtes pour chaque carte
    fluid_row_output <- list()
    
    # Pour chaque element du tableau
    for (i in seq(1, length(noms_cartes_nutri_dept), by = 2)) {
      
      fluid_row_output[[length(fluid_row_output) + 1]] <- fluidRow(
        tableau_cartes[[i]],
        if (i + 1 <= length(tableau_cartes)) tableau_cartes[[i+1]] else NULL
      )
    }
    
    # Generer les cartes pour chaque nutriment
    
    print("Génération des cartes pour chaque nutriment")
    for (i in seq_along(noms_cartes_nutri_dept)) {
      
      print(paste("Génération de la carte pour le nutriment :", nutriments_valides[i], "avec le nom :", noms_cartes_nutri_dept[i]))

      # TO FIX 1 ----
      # this is where the error appears. The above print gives me a list of length 7 with the correct values.
      # Then, I pass the same arguments to the output and drawing map function below
      # Bug 1 : it only gives the last element of the vector to generer_carte_nutri_dept() instead of all 7 elements (length(noms_cartes_nutri_dept) = 7)
      # Bug 2 : it only gives the last element of the vector 2 times, instead of looping 7 times

      output[[noms_cartes_nutri_dept[i]]] <- renderLeaflet({
      # TO FIX 2 ----
      # And here it breaks. Instead of getting each element of nutriment_valides, it only receives the last element of the vector.
        print(i) # only print 7 twice instead of 1 2 3 4 5 6 7
        carte_bilan_departemental(
          df_bilan_shape = bilan_nutri_dept_shape(), 
          produit = input$selecteur_MP,
          nutriment = nutriments_valides[i],
          mesure = "med"
        )
      })
    }
    
    return(do.call(tagList, fluid_row_output))
  })


ui.R

body <- dashboardBody(
  
  tabItems(
    tabItem(
        # Génération dynamiques des fluidRows
        uiOutput("all_cartes_nutri_dept")
        )
    )
)

虚拟数据

# Dummy Data for Nutrient Information and Departments
set.seed(123)

# Departments (for simulation purposes, can be any identifier)
departments <- c("Department A", "Department B", "Department C", "Department D")

# Simulate some nutritional data for 4 departments and 3 nutrients
df_bilan <- data.frame(
  nom_produit = rep(c("Product 1", "Product 2"), each = 4),
  nom = rep(departments, times = 2), # Department names
  humidite_med = runif(8, 10, 30),  # Random values for the nutrient
  proteines_med = runif(8, 2, 15),  # Random values for the nutrient
  lipides_med = runif(8, 5, 20)     # Random values for the nutrient
)

# Simulate available nutrients
colonnes_disponibles <- list(
  nutriments = c("humidite", "proteines", "lipides")
)

# Simulated product selection (input)
input <- list(selecteur_MP = "Product 1")  # Can be any valid product

任何如何解决

TO FIX 1
TO FIX 2
的想法。我认为唯一的问题是正确的变量没有被输入到
generer_carte_nutri_dept()

我对模块的了解太晚了,无法将它们包含在这个应用程序中,所以请不要在这个阶段建议它。但这是稍后的工作。

编辑:我将生成传单地图的代码移至主输出逻辑内。还是被打扰了。

r shiny reactive r-leaflet
1个回答
0
投票

我使用该问题的答案修复了它:R Shiny renderPlot 不尊重 for 循环中的父环境。问题在于对其中一个变量的惰性求值。

通过用类似 apply 的函数替换 for 循环,解决了这个问题。

for (i in seq_along(noms_cartes_nutri_dept)) {
    output[[noms_cartes_nutri_dept[i]]] <- generer_carte_nutri_dept(nutriments_valides[i])
    }

map(seq_along(noms_cartes_nutri_dept), function(i) {
        output[[noms_cartes_nutri_dept[i]]] <- generer_carte_nutri_dept(nutriments_valides[i])
    })
© www.soinside.com 2019 - 2024. All rights reserved.