Wawa
Wawa

Reputation: 73

Is there any other way to create dependent survey questionnaire using R Shiny?

I would like to create a survey questionnaire where some of the questions are dependent on other question. I tried to use shinysurveys package. Below is the data for the questionnaire in table form. The questionnaire is for illustration purposes only.

The algorithm behind this app would be Question 2 will pop up if user answer for question 1 is 1. Question 3 will pop up if user answer for question 1 is 2.  Both question 2 and question 3 will pop up if user answer for question 1 is 1 and 2.

Questions:-

  1. On a scale from 1-3. how much you love sushi?
    Answer selection: 1,2,3 (tick box multiple choice - can be more than 1 answer )
  2. Really?
    Answer selection: Yes, No (radio button multiple choice - only 1 answer)
  3. Test
    Answer selection: Yes, No (radio button multiple choice - only 1 answer)

Method 1 - I have tried the below code where I need to create my own input type, which is checkboxGroupInput using extendInputType but it doesn't work.

It will give this error if i tick box "1" and box "2" for question 1. And only show question that dependent on tick box "1".

This warning will be show Warning messages: 1: In if (input[[df$dependence1]] == df$dependence_value1) { : the condition has length > 1 and only the first element will be used.

extendInputType("checkbox", {
  shiny::checkboxGroupInput(
    inputId = surveyID(),
    label = surveyLabel(),
    choices = surveyOptions(),
  )
})
# Define a question as normal with the `input_type` set to the custom slider type defined above.
df_question <- data.frame(question = c("On a scale from 1-10, how much do you love sushi?", "On a scale from 1-10, how much do you love sushi?","On a scale from 1-10, how much do you love sushi?","Really", "Really", "Test"),
                              option = c("1", "2", "3", "Yes", "No", NA),
                              input_type = c("checkbox", "checkbox","checkbox","mc", "mc", "text"),
                              input_id = c("sushi_scale", "sushi_scale","sushi_scale","test", "test", "test2"),
                              dependence = c(NA, NA, NA,"sushi_scale", "sushi_scale", "sushi_scale"),
                              dependence_value = c(NA, NA,NA,"1", "1", "2"),
                              required = c(TRUE,TRUE,TRUE, TRUE, TRUE, TRUE))
# Watch it in action

  ui <- fluidPage(
    surveyOutput(df = df_question, "Sushi Scale Example")
  )
  server <- function(input, output, session) {
    renderSurvey()
  }
  shinyApp(ui, server)

enter image description here

enter image description here

enter image description here

Method 2 - Another way is to create a conditional panel in the UI and filter related data there. But, it is not convenient as I have to come up with several permutations. 

library(dplyr)
library(shinysurveys)
ui <- shiny::fluidPage(
    
    uiOutput('ui')
    
  )
  
server <- function(input, output, session) {
    
    df_question <- data.frame(question = c("Really", "Really", "Test"),
                              option = c("Yes", "No", NA),
                              input_type = c("mc", "mc", "text"),
                              input_id = c("test", "test", "test2"),
                              dependence = c(NA, NA, NA),
                              dependence_value = c("1", "1", "2"),
                              required = c(TRUE, TRUE, TRUE))
    
    
    output$ui <- renderUI({
      fluidPage(
        checkboxGroupInput(inputId = "Sushi_scale", label = "On a scale from 1-3, how much do you love sushi?",
                           choices = c("1","2", "3")),
        conditionalPanel(condition = "input.Sushi_scale == '1'", 
                         shinysurveys::surveyOutput(df_question %>% 
                                                      filter( `question` == "Really")) ,
                                                    theme = "#ffffff"),
        conditionalPanel(condition = "input.Sushi_scale == '2'", 
                         shinysurveys::surveyOutput(df_question %>% 
                                                      filter( `question` == "Test")) ,
                         theme = "#ffffff"),
        
        )
        
    })
    
    
  }
  
  shiny::shinyApp(ui = ui, server = server)

Method 3 - This method doesn't work as well. I tried to pass reactive value to the UI. 

library(dplyr)
library(shinysurveys)
ui <- shiny::fluidPage(
    
   uiOutput('ui')
    
)
  
server <- function(input, output, session) {
    
  df_question <- data.frame(question = c("Really", "Really", "Test"),
                              option = c("Yes", "No", NA),
                              input_type = c("mc", "mc", "text"),
                              input_id = c("test", "test", "test2"),
                              dependence = c(NA, NA, NA),
                              dependence_value = c("1", "1", "2"),
                              required = c(TRUE, TRUE, TRUE))
    
    vals <-reactiveValues()
    eventReactive(input$go,{
      
      if (input$Sushi_scale == "1"){
        vals$df <- df_question %>% filter(question == "Really")
      }
      
    })
    
    
    output$ui <- renderUI({
      fluidPage(
        checkboxGroupInput(inputId = "Sushi_scale", label = "On a scale from 1-3, how much do you love sushi?",
                           choices = c("1","2", "3")),
        shinysurveys::surveyOutput(vals$df) ,
                        theme = "#ffffff")
    })
    
}
  
shiny::shinyApp(ui = ui, server = server)

I discovered this website: https://github.com/EconometricsBySimulation/Shiny-Demos/tree/master/Survey where the writer creates a questionnaire via Shiny R. The demo is here: https://econometricsbysimulation.shinyapps.io/Survey/. The only thing is that I want the questionnaire to be on one page without having to click next to answer every question.

Are there any other recommendation to built this survey using Shiny R?

Upvotes: 1

Views: 1475

Answers (1)

Mikko Marttila
Mikko Marttila

Reputation: 11898

There’s a pull request for the shinysurveys package that would make the first method work. It’s a 5-character fix, so I really wouldn’t spend any time trying to find some other workaround for it until it’s merged. To use the fixed version now, install the PR branch with:

remotes::install_github("jdtrat/shinysurveys#43")

Upvotes: 1

Related Questions