Rs200000000000

W aplikacji shiny (by RStudio), po stronie serwera, mam reactive, który zwraca listę zmiennych analizując zawartość textInput. Lista zmiennych jest następnie używana w selectInput i / lub updateSelectInput.

Nie mogę tego zrobić. Jakieś sugestie? Podjąłem dwie próby. Pierwszym podejściem jest użycie reaktywnego outVar bezpośrednio do selectInput. Drugim podejściem jest użycie reaktywnego outVar w updateSelectInput. Ani działa.

Serwer.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")
  )
)

Jakiś czas temu, zamieściłem to samo pytanie na shiny-discuss, ale wzbudziło to małe zainteresowanie, więc pytam ponownie, z przeprosinami, https://groups.google.com/forum/#! topic/shiny-discuss / e0MgmMskfWo

Edit 1

@ Ramnath uprzejmie opublikował rozwiązanie, które wydaje się działać, oznaczone Edit 2 przez niego. Ale to rozwiązanie nie rozwiązuje problemu, ponieważ textinput jest po stronie ui zamiast po stronie server Jak to jest w moim problemie. Jeśli przeniosę textinput drugiej edycji Ramnatha na stronę server, problem pojawi się ponownie, a mianowicie: nic się nie pokazuje i RStudio się zawiesza. Okazało się, że owinięcie input$text w {[21] } sprawia, że problem znika.

Edit 2

W dalszej dyskusji Ramnath pokazał mi, że problem pojawia się, gdy serwer próbuje zastosować funkcję dynamiczną outVar zanim jej argumenty zostaną zwrócone przez textinput. Rozwiązaniem jest najpierw sprawdzenie, czy is.null(input$inBody) istnieje.

sprawdzanie istnienia argumentów jest kluczowym aspektem budowania błyszczącej aplikacji, więc dlaczego o tym nie pomyślałem? Tak, ale musiałem zrobić coś złego! Biorąc pod uwagę ilość czasu, jaki spędziłem na problemie, jest to gorzkie doświadczenie. Pokazuję po kodzie, jak sprawdzić istnienie.

Poniżej znajduje się kod Ramnatha z textinput przeniesiony na stronę server. Wywala RStudio więc nie próbuj to w domu. (Użyłem jego notacji)

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())
    })
  }
))

Sposób, w jaki zwykle sprawdzam istnienie, wygląda tak:

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

Kod Ramnatha jest krótszy:

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

Oba wydają się działać, ale będę to robić po swojemu: może niezrównoważony wspornik w mojej konstrukcji wcześniej uniemożliwił mi wykonanie czeku? Czek ramnatha jest bardziej bezpośredni.

Na koniec chciałbym zwrócić uwagę na kilka rzeczy o moich różnych próbach debugowania.

W moim debugowaniu quest, odkryłem, że istnieje opcja "rangi" priorytetu "wyjść" po stronie serwera, które zbadałem próbując rozwiązać mój problem, ale nie zadziałało, ponieważ problem był gdzie indziej. Mimo to, jest to interesujące wiedzieć i wydaje się nie bardzo dobrze znane w tym czasie:

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

W tej misji, ja również próbowałem try:

try(vars <- all.vars(parse(text = input$text)))
Było blisko, ale nie udało się tego naprawić.

Pierwsze rozwiązanie, na które natknąłem się było:

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

Przypuszczam, że interesujące byłoby wiedzieć, dlaczego to działało: czy to dlatego, że spowalnia wszystko wystarczająco? czy to dlatego, że as.character "czeka" na input$text, aby być nie-null?

Cokolwiek by to nie było, jestem niezmiernie wdzięczny Ramnathowi za jego wysiłek, cierpliwość i przewodnictwo.
Author: micstr, 2014-01-30

3 answers

Musisz użyć renderUI Po stronie serwera dla dynamicznych interfejsów użytkownika. Oto minimalny przykład. Zwróć uwagę, że drugie rozwijane menu jest reaktywne i dostosowuje się do zestawu danych wybranego w pierwszym. Kod powinien być zrozumiały, jeśli wcześniej miałeś do czynienia z błyszczącym.

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))
    })
  }
))

EDIT. Inne rozwiązanie za pomocą 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: zmodyfikowany przykład za pomocą parse. W tej aplikacji wprowadzona formuła tekstowa służy do dynamicznego wypełniania rozwijanego menu poniżej listą zmienne.

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())
    })
  }
))
 62
Author: Ramnath,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-01-31 16:06:43

Z tego co wiem, problem polega na tym, że input$inBody nie pobiera character, nawet jeśli selectInput funkcja otrzymuje character jako wartość, czyli value = "a+b+c". Rozwiązaniem jest zatem zawinięcie input$inBody w as.character

Następujące dzieła:

Podejście observe z updateSelectInput:

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

Podejście reactive z 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())
})

Edit: edytowałem moje pytanie z wyjaśnieniem na podstawie opinii Ramnatha. Ramnath wyjaśnił problem i dostarczył lepsze rozwiązanie, które daję jako edycję mojego pytania. Zatrzymam tę odpowiedź, ale nie zasługuje na głosy.

 2
Author: PatrickT,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-02 07:05:15

Serwer.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")
 1
Author: Ashish Markanday,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-05 03:00:01