values tutorial ejemplos app r shiny shiny-reactivity

tutorial - R brillante pasando reactivo para seleccionar opciones de entrada



shiny app r tutorial (3)

servidor.R

### This will create the dynamic dropdown list ### output$carControls <- renderUI({ selectInput("cars", "Choose cars", rownames(mtcars)) }) ## End dynamic drop down list ### ## Display selected results ## txt <- reactive({ input$cars }) output$selectedText <- renderText({ paste("you selected: ", txt() ,sep="") }) ## End Display selected results ##

ui.R

uiOutput("carControls"), br(), textOutput("selectedText")

En una aplicación brillante (por RStudio), en el lado del servidor , tengo un reactivo que devuelve una lista de variables mediante el análisis del contenido de una entrada de texto. La lista de variables se usa luego en selectInput y / o updateSelectInput .

No puedo hacer que funcione. ¿Alguna sugerencia?

He hecho dos intentos. El primer enfoque es usar el outVar reactivo directamente en selectInput . El segundo enfoque es usar el outVar reactivo en updateSelectInput . Ninguno de los dos funciona

servidor.R

shinyServer( function(input, output, session) { outVar <- reactive({ vars <- all.vars(parse(text=input$inBody)) vars <- as.list(vars) return(vars) }) output$inBody <- renderUI({ textInput(inputId = "inBody", label = h4("Enter a function:"), value = "a+b+c") }) output$inVar <- renderUI({ ## works but the choices are non-reactive selectInput(inputId = "inVar", label = h4("Select variables:"), choices = list("a","b")) }) observe({ ## doesn''t work choices <- outVar() updateSelectInput(session = session, inputId = "inVar", choices = choices) }) })

ui.R

shinyUI( basicPage( uiOutput("inBody"), uiOutput("inVar") ) )

Hace poco, publiqué la misma pregunta en shiny-discuss, pero ha generado poco interés, así que vuelvo a preguntar, con disculpas, https://groups.google.com/forum/#!topic/shiny-discuss/e0MgmMskfWo

Editar 1

@Ramnath ha publicado amablemente una solución que parece funcionar, denotada Edit 2 por él. Pero esa solución no soluciona el problema porque la entrada de textinput está en el lado ui lugar de en el lado del server ya que está en mi problema. Si muevo la textinput de textinput de la segunda edición de Ramnath al lado del server , el problema vuelve a surgir, es decir: nada se muestra y RStudio se cuelga. Descubrí que envolver input$text en as.character hace que el problema desaparezca.

Editar 2

En una discusión adicional, Ramnath me ha mostrado que el problema surge cuando el servidor intenta aplicar la función dinámica outVar antes de que sus argumentos hayan sido devueltos por la textinput de textinput . La solución es verificar primero si is.null(input$inBody) existe.

Verificar la existencia de argumentos es un aspecto crucial de la creación de una aplicación brillante , entonces, ¿por qué no pensé en eso? Bueno, lo hice, pero debo haber hecho algo mal. Considerando la cantidad de tiempo que gasté en el problema, es una experiencia amarga. Muestro después del código cómo verificar la existencia.

Debajo está el código de Ramnath con textinput movido al lado del server . Bloquea RStudio así que no lo intentes en casa. (He usado su notación)

library(shiny) runApp(list( ui = bootstrapPage( uiOutput(''textbox''), ## moving Ramnath''s textinput to the server side uiOutput(''variables'') ), server = function(input, output){ outVar <- reactive({ vars <- all.vars(parse(text = input$text)) ## existence check needed here to prevent a crash vars <- as.list(vars) return(vars) }) output$textbox = renderUI({ textInput("text", "Enter Formula", "a=b+c") }) output$variables = renderUI({ selectInput(''variables2'', ''Variables'', outVar()) }) } ))

La forma en que suelo verificar la existencia es así:

if (is.null(input$text) || is.na(input$text)){ return() } else { vars <- all.vars(parse(text = input$text)) return(vars) }

El código de Ramnath es más corto:

if (!is.null(mytext)){ mytext = input$text vars <- all.vars(parse(text = mytext)) return(vars) }

Ambos parecen funcionar, pero lo haré de la manera de Ramnath a partir de ahora: ¿quizás un soporte desequilibrado en mi construcción me había impedido anteriormente hacer que el cheque funcionara? El control de Ramnath es más directo.

Por último, me gustaría señalar un par de cosas sobre mis diversos intentos de depuración.

En mi búsqueda de depuración, descubrí que hay una opción para "clasificar" la prioridad de "resultados" en el lado del servidor, que exploré en un intento de resolver mi problema, pero no funcionó ya que el problema estaba en otra parte. Aún así, es interesante saber y parece no ser muy conocido en este momento:

outputOptions(output, "textbox", priority = 1) outputOptions(output, "variables", priority = 2)

En esa búsqueda, también intenté try :

try(vars <- all.vars(parse(text = input$text)))

Eso estuvo muy cerca, pero aun así no lo solucionó.

La primera solución con la que tropecé fue:

vars <- all.vars(parse(text = as.character(input$text)))

Supongo que sería interesante saber por qué funcionó: ¿es porque ralentiza bastante las cosas? ¿es porque as.character "espera" que input$text de input$text sea ​​no nulo?

Cualquiera que sea el caso, estoy extremadamente agradecido con Ramnath por su esfuerzo, paciencia y guía.


Por lo que puedo decir, el problema es que input$inBody no recupera un character aunque la función selectInput recibe un character como valor, es decir, value = "a+b+c" . La solución, por lo tanto, es ajustar la input$inBody en un carácter as.character

Los siguientes trabajos:

El enfoque de observe con updateSelectInput :

observe({ input$inBody vars <- all.vars(parse(text=as.character(input$inBody))) vars <- as.list(vars) updateSelectInput(session = session, inputId = "inVar", choices = vars) })

El enfoque reactive con selectInput :

outVar <- reactive({ vars <- all.vars(parse(text=as.character(input$inBody))) vars <- as.list(vars) return(vars) }) output$inVar2 <- renderUI({ selectInput(inputId = "inVar2", label = h4("Select:"), choices = outVar()) })

Editar: he editado mi pregunta con una explicación basada en los comentarios de Ramnath. Ramnath explicó el problema y proporcionó una mejor solución, que doy como una edición de mi pregunta. Guardaré esta respuesta, pero no merece los votos.


renderUI usar renderUI en el lado del servidor para IU dinámicas. Aquí hay un ejemplo mínimo. Tenga en cuenta que el segundo menú desplegable es reactivo y se ajusta al conjunto de datos que elija en el primero. El código debería explicarse por sí mismo si ya has tratado con brillo antes.

runApp(list( ui = bootstrapPage( selectInput(''dataset'', ''Choose Dataset'', c(''mtcars'', ''iris'')), uiOutput(''columns'') ), server = function(input, output){ output$columns = renderUI({ mydata = get(input$dataset) selectInput(''columns2'', ''Columns'', names(mydata)) }) } ))

EDITAR. Otra solución usando updateSelectInput

runApp(list( ui = bootstrapPage( selectInput(''dataset'', ''Choose Dataset'', c(''mtcars'', ''iris'')), selectInput(''columns'', ''Columns'', "") ), server = function(input, output, session){ outVar = reactive({ mydata = get(input$dataset) names(mydata) }) observe({ updateSelectInput(session, "columns", choices = outVar() )}) } ))

EDIT2: Ejemplo modificado usando parse . En esta aplicación, la fórmula de texto ingresada se usa para rellenar dinámicamente el menú desplegable a continuación con la lista de variables.

library(shiny) runApp(list( ui = bootstrapPage( textInput("text", "Enter Formula", "a=b+c"), uiOutput(''variables'') ), server = function(input, output){ outVar <- reactive({ vars <- all.vars(parse(text = input$text)) vars <- as.list(vars) return(vars) }) output$variables = renderUI({ selectInput(''variables2'', ''Variables'', outVar()) }) } ))