ejemplos - shiny examples r
Problema brillante(R) al actualizar el mapa de folletos dentro de la aplicaciĆ³n (2)
Gracias Florian por su ayuda, describiré precisamente cómo lo logré:
output$answ<- renderText({
paste("Choix départements:", input$choix_depa)
})
observeEvent(input$choix_depa, {
choice=input$choix_depa
})
map_reactive <- eventReactive(input$choix_depa,{
... merging and creating contours_IRIS (shape file)
and data_BPC given input$choix_depa ...
map_WGS84 = spTransform(
merge(contours_IRIS, data_BPC, by.x = ''CODE_IRIS'', by.y = ''IRIS''),
CRS("+init=epsg:4326")
)
list(map = map_WGS84)
})
observeEvent(input$choix_var_pop, {XXXXXXXXX})
... defining variables...
output$Carte_Pop <- renderLeaflet({
compulsive = map_reactive()$map
label = label_reac_pop()
var = var_reac_pop()
col = col_reac_pop()
type = type_reac_pop()
unite = unite_reac_pop()
values_var = compulsive@data[,var]
leaflet(compulsive) %>%
})
Lo que también fue "importante" aquí fue agregar la "lista" al final del evento Reactivo, para llamar al "map_reactive $ map" más tarde. Problema resuelto !
Estoy usando Shiny y tengo un problema con Leaflet.
Lo que quiero hacer : el objetivo final de mi proyecto es seleccionar condados franceses específicos. Cuando se seleccionan esos condados, creo on-the-go (fusionando) el archivo de formas (que es necesario para trazar el mapa en Leaflet) y la base de datos que contiene todo tipo de datos públicos (como el número de población, ect. ..) que corresponden solo a esos condados específicos.
Mi problema : sé que la "fusión" se hace bien, dentro de la aplicación Shiny. PERO, mi Outputmap no quiere funcionar.
Detalles : en realidad, lancé mi "fusión y trazado" en otro script .R, y funciona perfectamente (solo definí "manualmente" antes de ejecutar el script qué condados quería trazar). En mi ShinyApp, esta elección la toma la variable input$choix_depa
.
Ahora un poco de código. Tengo tres scripts que reaccionan simultáneamente: global.R ui.R y server.R (así es como funciona Shiny como usted sabe). Para global.R (solo muestro aquí la parte "interessant"), cargo el archivo de la base de datos que contiene los datos de todos los condados (¡no los archivos de forma! Solo los datos)
setwd(''path'')
data_BP = read_delim(
"database-allFrance.csv",
",",
na = "empty",
quote = "/"",
locale = locale(encoding = ''windows-1252'')
)
En el ui.R (interfaz de usuario) tengo mi "selección" de condados:
shinydashboard::tabItem(tabName= "Departements", class = ''active'',
shiny::fluidPage(
shiny::absolutePanel(
draggable = FALSE,
fixed = TRUE,
top = 60, left = "auto", right = 20, bottom = "auto",
width = 330, height = "auto",
wellPanel(
shiny::h4("Départements"),
selectizeInput(inputId = "choix_depa", label = "",multiple=TRUE,
choices = seq(1,95))
)
), textOutput("answ")
),
El selectizeInput
es el botón que permite al usuario elegir uno o más condados en el seq(1,95)
.
Y en el servidor.R (más importante) tengo:
ObserveEvent(input$choix_depa, {
output$answ<- renderText({
paste("You choose", input$choix_depa)
})
choice=input$choix_depa
print(choice)
for (i in input$choix_depa){
setwd(sprintf("path/county%s",i))
assign(paste("contouriris",i,sep=""), readOGR(
dsn = "contours_IRIS_BP.shp",
layer = "contours_IRIS_BP",
verbose = FALSE,
encoding = ''UTF-8''
))
print("modification en cours...")
assign(paste("data_BP",i,sep=""),subset(data_BP,as.numeric(as.character(data_BP$IRIS))>=as.numeric(i)*10000000&as.numeric(as.character(data_BP$IRIS))<(as.numeric(i)+1)*10000000))
}
if (length(input$choix_depa)>=1){
contours_IRIS <- get(paste("contouriris",input$choix_depa[1],sep=""))
data_BPC <- get(paste("data_BP",input$choix_depa[1],sep=""))
}
if (length(input$choix_depa)>1){
for (i in input$choix_depa[-1]){
contours_IRIS <- rbind(contours_IRIS,get(paste("contouriris",i,sep="")))
data_BPC <- rbind(data_BPC,get(paste("data_BP",i,sep="")))
}
}
map_WGS84 = spTransform(
merge(contours_IRIS, data_BPC, by.x = ''CODE_IRIS'', by.y = ''IRIS''),
CRS("+init=epsg:4326")
)
# Correction of names :
names(map_WGS84)[names(map_WGS84) == "TYP_IRIS.x"] <- "TYP_IRIS"
})
No tienes que entender todo este código. Puede elegir los condados en la variable input$choix_depa
. Este tipo de variable es como ["4", "87"] si los condados 4 y 87 son seleccionados por el usuario dentro de la aplicación (por ejemplo). Tengo en mi computadora 95 carpetas (una para cada condado). Yo uso setwd para ir a la ruta correcta, y cargo el "archivo de forma" en el contouririsK
del contouririsK
con K el número del condado. En el ejemplo anterior tendríamos contouriris4
y countouriris87
. Esos archivos de formas se fusionan en contours_IRIS
. Hago lo mismo cosa con el archivo de datos, tomé los datos que están asociados con esos condados y data_BPC
todos los archivos en el data_BPC
. (Si tomo el ejemplo anterior, tendríamos data_BPC4
y data_BPC87
que se fusionan en el data_BPC
).
Después de esto, uso ambas variables ( contours_IRIS
y data_BPC
) para crear la variable map_WGS84
(necesitaré esta variable para LeafletOutput).
OK entonces, después de esta elección de condados que quiero trazar en el mapa del Folleto, tengo que elegir las variables en las que estoy interesado. Este es otro menú, no escribo aquí todo el código (no es necesario)
observeEvent(input$choix_var_pop, {XXXXXXXXX})
La elección de la variable que el usuario desea trazar en el mapa está en la input$choix_var_pop
. Después de esto, creo las variables específicas que necesitaré en mi LeafletMap:
label_reac_pop = reactive({as.character(input$choix_var_pop)})
var_reac_pop = reactive({dico$Variable[dico$Label == label_reac_pop()]})
col_reac_pop = reactive({as.character(dico$Couleur[dico$Label == label_reac_pop()])})
type_reac_pop = reactive({as.character(dico$Type[dico$Label == label_reac_pop()])})
unite_reac_pop = reactive({ifelse(as.character(type_reac_pop()) == "Pct", " %", "")})
Por último, tramo el LeafletMap: (he reducido mucho para mayor claridad el código a continuación)
output$Carte_Pop <- renderLeaflet({
label = label_reac_pop()
var = var_reac_pop()
col = col_reac_pop()
type = type_reac_pop()
unite = unite_reac_pop()
values_var = map_WGS84@data[,var]
leaflet(map_WGS84) %>%
addProviderTiles("CartoDB.PositronNoLabels") %>%
addProviderTiles("CartoDB.PositronOnlyLabels") %>%
setView(lng = 2.468738900000062, lat = 49.19316, zoom = 7) %>%
clearShapes() %>%
clearPopups() %>%
})
Por supuesto, llamo a esta salida $ Carte_Pop en el archivo ui.R, para trazarlo. Bien, entonces, ¿cuál es el resultado de todo esto? Como mencioné antes, este script funciona cuando está "solo", y cuando no hay input$choix_depa
(ingreso manualmente los condados que quiero fusionar en una matriz, y se combinan bien, y el mapa está bien trazado ) PERO cuando estoy en ShinyApp con mis 3 scripts (global.R, ui.R y server.R), el "nuevo" valor del "mapa" no está "guardado" .
Por ejemplo: si elijo (en mi script solo) fusionar y trazar los condados número 4 y 87, funciona bien (la parte de fusión y la parte de trazado funcionan bien).
PERO cuando lanzo mi ShinyApp, cuando elijo los condados que quiero (por ejemplo 13 y 91), INCLUSO SI los contours_IRIS
y el data_BPC
están bien fusionados con los datos correspondientes a 13 y 91, así que supongo que el map_WGS84
que es creado DENTRO del observeEvent(input$choix_depa....)
CORRESPONDE BIEN a 13 y 91, cuando solicito trazar una variable específica (después del observeEvent(input$choix_var_pop)
el mapa que se traza NO ES el mapa creado antes, pero el "MAPA antiguo" con 4 y 87 (el mapa que se creó en el "script solo" ... ¡antes de lanzar ShinyApp!). Pero estoy seguro al 100% de que el MAP creado dentro del observeEvent(input$choix_depa .... )
es bueno, pero el "valor" de este MAP no es "guardado" por ShinyApp (usan en su lugar el valor anterior para el MAP ...).
Entonces mi pregunta es: ¿qué debo hacer para trazar el MAPA BUENO NUEVO (creado dentro de la APLICACIÓN) en lugar del VIEJO MALO (creado ANTES y FUERA de la aplicación ...)?
Este problema es un poco "complejo", si tienes alguna pregunta, ¡no dudes en preguntar!
Gracias ! :)
Resumen: cuando desee hacer que un resultado dependa de otras expresiones, debe usar un evento Reactivo, o almacenar el objeto en un valor reactivo y actualizarlo desde un evento de observación.
De acuerdo, leí tu pregunta y aquí están mis pensamientos:
ObserveEvent(input$choix_depa, {
output$answ<- renderText({
paste("You choose", input$choix_depa)
})
Esta es una mala práctica. los observadores solo deben usarse para efectos secundarios, no para crear resultados. Eso debería convertirse en:
output$answ<- renderText({
paste("You choose", input$choix_depa)
})
ObserveEvent(input$choix_depa, {
....
renderText también se activará siempre que la entrada $ choix_depa cambie, ya que es reactiva en eso. Entonces no hay necesidad de colocarlo en el observador.
map_WGS84 = spTransform(
merge(contours_IRIS, data_BPC, by.x = ''CODE_IRIS'', by.y = ''IRIS''),
CRS("+init=epsg:4326")
)
¿Qué tipo de objeto es map_WGS84? Esto solo funcionará si es un valor reactivo. De lo contrario, no sobrescribes la variable global, sino solo la local dentro de la función observeEvento. Una vez que el evento observe, el mapa global_WGS84 no ha cambiado. Creo que este es el problema aquí.
La mejor opción es, probablemente, hacer de esto un evento Reactivo , en lugar de un evento de observación, ya que desea que produzca resultados que se puedan usar en cualquier otro lugar. La otra opción es almacenar map_WGS84 en una expresión de valores reactivos, y sobrescribirlo desde su evento observe.