1
votes

I am trying to build a 'data explorer' shiny app which contains DataTables, ggplot2 graphs and wilcox.test results. I can't seem to make the wilcox.test to work though.

Outside the shiny app, things work as it should:

dat <- data.frame(outcome=sample(c("died","survived",NA), 20, TRUE),
       cntr=sample(c("hospa","hospb"), 20, TRUE), 
       s=rnorm(20), 
       t=rnorm(20), stringsAsFactors=FALSE)     

wilcox.test(dat$s ~ dat$outcome)

Results:

Wilcoxon rank sum test

data: dat$s by dat$outcome W = 25, p-value = 0.3301 alternative hypothesis: true location shift is not equal to 0

Within the shiny app, the code below gives an 'Error: grouping factor > must have exactly 2 levels'. (graphs & tables work fine; I have omitted these for clarity).

    library(shiny)
    library(dplyr)

    dat <- data.frame(outcome=sample(c("died","survived",NA), 20, TRUE),
       cntr=sample(c("hospa","hospb"), 20, TRUE), 
       s=rnorm(20), 
       t=rnorm(20), stringsAsFactors=FALSE)

    ui <- navbarPage(
          sidebarLayout(
            sidebarPanel(
             selectInput(inputId = "y", 
              label = "Y-axis:",
              choices = c("s"="s", "t"="t"), 
              selected = "s"),
             selectInput(inputId = "z", 
              label = "Color by:",
              choices = c("outcome", "cntr"),
              selected = "outcome")
                  ),

            mainPanel(
             tabsetPanel(id="tabspanel", type = "tabs",
              tabPanel(title = "Wilcox"),
              h4(textOutput(outputId = "p")))
                   )
                  )
                 )

    server <- function(input, output, session) {
                 df <- reactive({
                              data.frame(input$y, input$z)
                          })

                 output$p <- renderText({
                                 wilcox.test(df()[,1] ~ df()[,2])
                                    })

                                              }

    shinyApp(ui=ui, server=server)

If the code is rewritten:

    wilcox.test(dat$s, dat$outcome)

then the error is 'Error: 'x' must be numeric'.

Can someone help?

2

2 Answers

2
votes

The issue you are having is that the line

data.frame(input$y, input$z)

gets translated to something like

data.frame("s", "outcome")

which can't be reasonably handeled by wicox.text. You should use the following instead

data.frame(dat[[input$y]], dat[[input$z]])

There were also some other minor issues. See the code code below for a full fix.

library(shiny)
library(dplyr)

dat <- data.frame(outcome=sample(c("died","survived",NA), 20, TRUE),
                  cntr=sample(c("hospa","hospb"), 20, TRUE), 
                  s=rnorm(20), 
                  t=rnorm(20), stringsAsFactors=FALSE)

ui <- navbarPage(
  sidebarLayout(
    sidebarPanel(
      selectInput(inputId = "y", 
                  label = "Y-axis:",
                  choices = c("s"="s", "t"="t"), 
                  selected = "s"),
      selectInput(inputId = "z", 
                  label = "Color by:",
                  choices = c("outcome", "cntr"),
                  selected = "outcome")
    ),

    mainPanel(
      tabsetPanel(id="tabspanel", type = "tabs",
                  tabPanel(title = "Wilcox",
                  verbatimTextOutput(outputId = "p")))
    )
  )
)

server <- function(input, output, session) {
  df <- reactive({
    data.frame(dat[[input$y]], dat[[input$z]])
  })

  output$p <- renderPrint({
    wilcox.test(df()[,1] ~ df()[,2])
  })

}

shinyApp(ui=ui, server=server)
0
votes

Gregor's guess is quite spot on; below snippet from the server codes:

    dat_subset <- reactive({
        req(input$selected_type) 
         filter(dat, outcome %in% input$selected_type)
          })

    output$scatterplot <- renderPlot({
         ggplot(data = dat_subset(), aes_string(x = input$x, y = input$y, color = input$z)) + geom_boxplot() + labs()
          })

    output$nsdtable <- DT::renderDataTable({
            DT::datatable(data = dat_subset()[, 1:4], 
              options = list(pageLength = 10), 
              rownames = FALSE)
          })