我正在开发 R Shiny 应用程序。用户上传他的数据文件,它会创建中值的传单地图。困难在于我需要为每个变量生成映射,但每个文件之间的数字可能不同。
数据是反应式科幻小标题,因此提供reprex将会很困难。
问题是只有最后一个变量被多次生成。
# 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))
})
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 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])
})