2014-10-08 2 views
1

Я пытался расширить второе решение, отправленное Ramnath (тот, который использует updateSelectInput) в проблеме, первоначально размещенной на R shiny passing reactive to selectInput choices. Я хотел бы разрешить пользователю выбирать входы из иерархической серии входов, где выбор в каждом из вариантов обновляет возможные значения в следующем выборе. В качестве примера, в следующем, я модифицирую код Ramnath, просто добавив третий вход, в котором перечислены значения переменной, выбранной во втором входе. Этот пример основан на наборах данных mtcars и iris и был запущен на R v 3.1.1 и RStudio v 0.98.1062. Он не выдает ошибки, но вы увидите, что я застрял в том, как добавить второй reactive(), который принимает в качестве своего ввода комбинацию input$dataset и input$column.R Блестящий: передача нескольких, успешных реактивов для selectInput

library(shiny) 

runApp(list(

    ui = bootstrapPage(
    selectInput('dataset', 'Choose data set', c('mtcars', 'iris')), 
    selectInput('columns', 'Choose variable', ""), 
    selectInput('values', 'Show values', "") 
), 

    server = function(input, output, session){ 

    # updates variable names based on selected dataset 
    outVar = reactive({ 
     names(get(input$dataset)) 
    }) 

    # i want this to update the values of the selected variable 
    outVar2 = reactive({ 
     sort(unique(get(input$dataset)[, 2])) # this works but of course I don't want the second variable every time 
     #sort(unique(get(input$dataset)[, input$columns])) # this fails but this is the idea I'm after 
    }) 

    # i want these to update the UI based on the reactive output above 
    observe({ 
     updateSelectInput(session, "columns", choices = outVar()) 
     updateSelectInput(session, "values", choices = outVar2()) 
    })  
    } 
)) 
+1

возможного дубликат [R блестящих Попутно реактивных к selectInput выбора] (HTTP: // StackOverflow. com/questions/21465411/r-shiny-pass-reactive-to-selectinput-choice), один из способов сделать то, что вы хотите, - это обернуть 'selectInput' в' renderUI' на стороне сервера. – Alex

ответ

3

Отвечая на мой первый вопрос. Кажется, что это старо, но, поскольку я играл с Shiny на прошлой неделе, я решил, что я помогу ответить на этот вопрос напрямую.

Чтобы ответить на вопрос напрямую, инструкция sort(unique(get(input$dataset)[, input$columns])) не подведет, это заявление observe. Поскольку и outVar(), и outVar2() находятся в операторе observe, оператор observe будет запускаться при изменении любой переменной. Поэтому, когда изменение ко второму selectInput (переменная input$columns), это фактически приведет к обновлению первого selectInput через updateSelectInput(session, "columns", choices = outVar()).

Это затем сбрасывает раскрывающийся список столбцов обратно к исходному выбору, заставляя его выглядеть так, как будто приложение сломано. Чтобы увидеть это в замедленном движении, я бы рекомендовал добавить browser() вызов в observe заявлении как код шаги через:

observe({ 
    browser() 
    updateSelectInput(session, "columns", choices = outVar()) 
    updateSelectInput(session, "values", choices = outVar2()) 
}) 

В целом, я разгонял observe заявление в 2 observeEvent заявления (я получил ошибки, когда только после того, как я изменил набор данных, разблокировав заявление до двух отдельных операторов observe). При обертывании updateSelectInput функции в observeEvent они будут только пытаться бежать, когда необходимый вход фактически обновляются, как показано ниже:

library(shiny) 

runApp(list(

    ui = bootstrapPage(
    selectInput('dataset', 'Choose data set', c('mtcars', 'iris')), 
    selectInput('columns', 'Choose variable', ""), 
    selectInput('values', 'Show values', "") 
), 

    server = function(input, output, session){ 

    # updates variable names based on selected dataset 
    outVar = reactive({ 
     names(get(input$dataset)) 
    }) 

    # i want this to update the values of the selected variable 
    outVar2 = reactive({ 
     if (input$columns == "") return() 
     sort(unique(get(input$dataset)[, input$columns])) 
    }) 

    # create separate observeEvents to 
    observeEvent(input$dataset, { 
     updateSelectInput(session, "columns", choices = outVar()) 
    }) 

    observeEvent(input$columns, { 
     updateSelectInput(session, "values", choices = outVar2()) 
    }) 

    } 
)) 
Смежные вопросы