0
votes

So I am having a little trouble with listing inputs within functions, particularly ezANOVA(). Here is what I have for code so far:

ui.R:

library(shiny)

shinyUI(pageWithSidebar(

  headerPanel('Analysis of Variance'),

  sidebarPanel(

    fileInput("file1", "CSV File", accept=c("text/csv", "text/comma-separated-values,text/plain", ".csv")),

    checkboxInput("header", "Header", TRUE),

    radioButtons('sep', 'Separator',c(Comma=',',Semicolon=';',Tab='\t'),','),

    uiOutput('var') 
  ),

  mainPanel( 

    tableOutput('aovSummary')

  )
)
)

server.R:

library(shiny)
library(ez)

shinyServer(function(input, output) {

  csvfile <- reactive({
    csvfile <- input$file1
    if (is.null(csvfile)){return(NULL)}
    dt <- read.csv(csvfile$datapath, header=input$header, sep=input$sep)
    dt
  })

  output$var <- renderUI({
    if(is.null(input$file1$datapath)){return()}

    else{
      return(list(radioButtons("estimate", "Please Pick The Dependent Variable",  choices = names(csvfile())),
              radioButtons("between1", "Please Pick The Between Subjects Factor", choices = names(csvfile())),
              radioButtons("within1", "Please Pick The Within Subjects Factor", choices = names(csvfile())),
              radioButtons("sid", "Please Pick The Subject Id Variable", choices = names(csvfile())),
              actionButton("submit", "Submit")))
  }

})


output$aovSummary = renderTable({

  if(is.null(input$file1$datapath)){return()}

  if(input$submit > 0){

    aov.out <- ezANOVA(data = csvfile(), dv = .(input$estimate), wid = .(input$sid), between = .(input$between1), 
                   within = .(input$within1), detailed = TRUE, type = "III")
    return(aov.out)

  }
})
})

Here is the data I have been testing it with:

    Animal  Visit   Dose    Estimate
    2556    0   3   1.813206946
    2557    0   3   1.933397744
    2558    0   3   1.689893603
    2559    0   3   1.780301984
2560    0   3   1.654374476
2566    0   10  3.401283412
2567    0   10  3.015958525
2568    0   10  2.808705611
2569    0   10  3.185718418
2570    0   10  2.767128836
2576    0   30  3.941412617
2577    0   30  3.793328436
2578    0   30  4.240736154
2579    0   30  3.859611218
2580    0   30  4.049743097
2586    0   100 5.600261483
2587    0   100 5.588115651
2588    0   100 5.089081008
2589    0   100 5.108262681
2590    0   100 5.343876403
2556    27  3   1.453587471
2557    27  3   1.994413484
2558    27  3   1.638132168
2559    27  3   2.138289747
2560    27  3   1.799769874
2566    27  10  3.302851871
2567    27  10  3.014199997
2568    27  10  3.190990162
2569    27  10  3.577924375
2570    27  10  3.537461068
2576    27  30  4.470837132
2577    27  30  4.081833308
2578    27  30  4.497192825
2579    27  30  4.205494309
2580    27  30  4.234496088
2586    27  100 6.054284369
2587    27  100 5.436697078
2588    27  100 5.398721492
2589    27  100 4.990794986
2590    27  100 5.573305744
2551    0   3   1.838550166
2552    0   3   1.847992942
2553    0   3   1.349892703
2554    0   3   1.725937126
2555    0   3   1.534652719
2561    0   10  2.931535704
2562    0   10  2.947599556
2563    0   10  3.092658629
2564    0   10  2.837625632
2565    0   10  2.970227467
2571    0   30  4.00746885
2572    0   30  3.921844968
2573    0   30  3.575724773
2574    0   30  4.17137839
2575    0   30  4.25251528
2581    0   100 4.785295667
2582    0   100 5.610955803
2583    0   100 5.497109771
2584    0   100 5.262724458
2585    0   100 5.430003698
2551    27  3   1.9326519
2552    27  3   2.313193186
2553    27  3   1.815261865
2554    27  3   1.345218914
2555    27  3   1.339432001
2561    27  10  3.305894401
2562    27  10  3.192621055
2563    27  10  3.76947789
2564    27  10  3.127887366
2565    27  10  3.231750087
2571    27  30  4.306556353
2572    27  30  4.232038905
2573    27  30  4.042378186
2574    27  30  4.784843929
2575    27  30  4.723665015
2581    27  100 5.601181262
2582    27  100 5.828647795
2583    27  100 5.652171222
2584    27  100 5.326512658
2585    27  100 6.009774247

The error I receive in the browser is:

"input$estimate" is not a variable in the data frame provided.

So, the function ezANOVA() is not using the actual variable name but rather the string "input$estimate", that is not what I want it to do.

How would I go about fixing this problem or is it helpless? Thanks in advance for all your help!

1

1 Answers

0
votes

You need to dynamically construct the call to ezANOVA(), i.e. use the value of the strings in your input variables to define the function call. Due to its LISP heritage, this is relatively easy in R via eval. (Relatively easy because strings are still painful in R and you need to manipulate strings to make this work). Here's a minimal working version of your code.

server.R

library(shiny)
library(ez)

shinyServer(function(input, output) {

    csvfile <- reactive({
        csvfile <- input$file1
        if (is.null(csvfile)){return(NULL)}
        dt <- read.csv(csvfile$datapath, header=input$header, sep=input$sep)
        dt
    })

    output$var <- renderUI({
        if(!is.null(input$file1$datapath)){
            d <- csvfile()
            anova.opts <- list(
                            radioButtons("estimate", "Please Pick The Dependent Variable",  choices = names(d)),
                            radioButtons("between1", "Please Pick The Between Subjects Factor", choices = names(d)),
                            radioButtons("within1", "Please Pick The Within Subjects Factor", choices = names(d)),
                            radioButtons("sid", "Please Pick The Subject Id Variable", choices = names(d)),
                            actionButton("submit", "Submit")
                        )
            anova.opts
        }

    })


    output$aovSummary = renderTable({

        if(!is.null(input$submit)){

            aov.out <- eval(parse(text=paste(
                                "ezANOVA(data = csvfile()
                               , dv = .(", input$estimate, ") 
                               , wid = .(", input$sid, ")
                               , between = .(", input$between1, ")
                               , within = .(", input$within1, ")
                               , detailed = TRUE, type = \"III\")")))
        aov.out$ANOVA
        }
    })
})

ui.R

library(shiny)

shinyUI(pageWithSidebar(

    headerPanel('Analysis of Variance'),

    sidebarPanel(

        fileInput("file1", "CSV File", accept=c("text/csv", "text/comma-separated-values,text/plain", ".csv")),

        checkboxInput("header", "Header", TRUE),

        radioButtons('sep', 'Separator',c(Comma=',',Semicolon=';',Tab='\t', `White Space`=''),''),

        uiOutput('var') 
    ),

    mainPanel( 

        tableOutput('aovSummary')

    )
)
)

I've changed/fixed a number of smaller issues, but the two most significant changes not related to eval() were:

  1. Including an option for letting R do its usual thing with white-space as a field separater.
  2. Changed the render function to include the actual ANOVA table. ezANOVA returns a list, the first entry of which is always ANOVA and contains the ANOVA table. However, there are sometimes further entries for assumption tests and post-hoc corrections, e.g. Mauchly's Test for Sphericity and Huynh-Feldt correction. You really need to add logic to deal with these when they're present.

Code style is also an issue -- it's better to get rid of empty if blocks followed by a full else and instead just test for the condition where you actually have code to run. Let R "fall off" the end of the function simulate a non existent return value.

I'm assuming UI improvements were waiting for a working example, but you need to consider:

  1. meaningful defaults, perhaps on variable type, for the different arguments and/or not reacting to the radio buttons, instead only reacting to an action button. Otherwise you get confusing errors from ezANOVA while you're setting the values.
  2. what happens if you have pure between or pure within designs?

You might also want to take a look at conditionalPanel() for hiding further options until an initial option (data file) is set in a meaningful way.