Shiny df interpreted as a function (can't perform plotting & group_by)

Viewed 31

This is my first time doing anything big in Shiny so I'm a bit lost.

I have this bit of half-done code, but nothing is really working so I have three questions:

  1. for the Stats tab I want it to display what's in "statsfun" as a little table.

The error is:

Error in UseMethod("group_by") : 
  no applicable method for 'group_by' applied to an object of class "function"

I don't even really knows where this should go and don't fully understand what is going on. I suspect it has something to do with the reactive df???

  1. For my plot it gives back the error
Error in eval(substitute(expr), data, enclos = parent.frame()) : 
  invalid 'envir' argument of type 'closure'

Basically the plot should return a plot based on the columns in the dataframe that the user selects.

(it doesn't work in ggplot either)

  1. I want to add more plot choices for the user and figured that if I do a conditional panel it will only display if the checkbox is ticked. The text displays but the selectInput bit doesn't. Anything I can do about this?

I think the problem in 1 and 2 lies in that something interprets "df" as a function and not a data.frame.

#load packages
library(dplyr)
library(tidyverse)
library(ggplot2)
library(phonR)
library(shiny)
#ui
ui <- shinyUI(fluidPage(
  titlePanel("Formant Plotter"),
  fluidRow(
    column(2,
           wellPanel(
             h3("File Upload"),
             fileInput("file1", "Choose .csv file",
                       accept=c("text/csv",
                                "text/comma-separated-values,text/plain",
                                ".csv")),
             helpText(em("Please do not upload any file that could contain confidential data")
             )),
           wellPanel(
             h3("Select your columns"),
             fluidRow(
               column(width=6,
                      selectInput("f1", "F1", "", selected="")
               ),
               column(width=6,
                      selectInput("f2", "F2", "", selected="")
               )
             ),
             selectInput("vowel", "Vowel", "", selected=""),
                      checkboxInput(inputId="spkrs", "Are there multiple speakers in your data?", TRUE),
             #conditional panel selectbox does not show up!!!
                      conditionalPanel(
                        condition = "input$spkrs == true",
                        selectInput= "speaker", strong("Speakers"), ""),
           ),
           wellPanel(
             h3("Plot settings"),
           
           )
           ),
    column(10,
           wellPanel(
             tabsetPanel(type="tabs",
                         tabPanel("Table", tableOutput("contents")),
                         tabPanel("Summary", tableOutput("stats")),
                         tabPanel("Formant Plot", plotOutput("plot")))
  )

  )
    )
)
)

#server
server <- shinyServer(function(input, output, session) {
  data <- reactive({ 
    req(input$file1)
    inFile <- input$file1 
    df <- read.csv(inFile$datapath, header=TRUE, sep=",",
                   quote='"')
    updateSelectInput(session, inputId="f1", label="F1",
                      choices=names(df), selected=names(df)[1]
                      [sapply(df, is.numeric)])
    updateSelectInput(session, inputId="f2", label="F2",
                      choices=names(df), selected=names(df)[2]
                      [sapply(df, is.numeric)])
    updateSelectInput(session, inputId="vowel", label="Vowel",
                      choices=names(df), selected=names(df)[3]
                      [sapply(df, is.character)])
    updateSelectInput(session, inputId="speaker", label="Speakers",
                      choices=names(df), selected=names(df)[4])
    return(df)

  })

  output$contents <- renderTable({
    data()
  })
  output$plot <- renderPlot({
    plot <- with(df, plotVowels(f1=get(input$f1), f2=get(input$f2),
                                var.sty.by=get(input$vowel),
                                pretty=TRUE))
    plot(plot)
  })
 
  output$stats <- renderTable({
    statfun <- data %>%
      group_by(get(input$vowel)) %>%
      summarise(meanf1=mean(input$ycol),
                meanf2=mean(input$xcol),
                sdf2(sd(input$xcol)))
    statfun()
  })
})

shinyApp(ui, server)

Thanks in advance, I know it's a lot, I just hope someone can help me figure it out.

1 Answers

When accessing a reactive expression you need to append () - as you did in your renderTable call:

#load packages
library(dplyr)
library(tidyverse)
library(ggplot2)
# library(phonR)
library(shiny)

#ui
ui <- shinyUI(fluidPage(
  titlePanel("Formant Plotter"),
  fluidRow(
    column(2,
           wellPanel(
             h3("File Upload"),
             fileInput("file1", "Choose .csv file",
                       accept=c("text/csv",
                                "text/comma-separated-values,text/plain",
                                ".csv")),
             helpText(em("Please do not upload any file that could contain confidential data")
             )),
           wellPanel(
             h3("Select your columns"),
             fluidRow(
               column(width=6,
                      selectInput("f1", "F1", "", selected="")
               ),
               column(width=6,
                      selectInput("f2", "F2", "", selected="")
               )
             ),
             selectInput("vowel", "Vowel", "", selected=""),
             checkboxInput(inputId="spkrs", "Are there multiple speakers in your data?", TRUE),
             #conditional panel selectbox does not show up!!!
             conditionalPanel(
               condition = "input$spkrs == true",
               selectInput= "speaker", strong("Speakers"), ""),
           ),
           wellPanel(
             h3("Plot settings"),
             
           )
    ),
    column(10,
           wellPanel(
             tabsetPanel(type="tabs",
                         tabPanel("Table", tableOutput("contents")),
                         tabPanel("Summary", tableOutput("stats")),
                         tabPanel("Formant Plot", plotOutput("plot")))
           )
           
    )
  )
)
)

#server
server <- shinyServer(function(input, output, session) {
  data <- reactive({ 
    req(input$file1)
    inFile <- input$file1 
    df <- read.csv(inFile$datapath, header=TRUE, sep=",",
                   quote='"')
    updateSelectInput(session, inputId="f1", label="F1",
                      choices=names(df), selected=names(df)[1]
                      [sapply(df, is.numeric)])
    updateSelectInput(session, inputId="f2", label="F2",
                      choices=names(df), selected=names(df)[2]
                      [sapply(df, is.numeric)])
    updateSelectInput(session, inputId="vowel", label="Vowel",
                      choices=names(df), selected=names(df)[3]
                      [sapply(df, is.character)])
    updateSelectInput(session, inputId="speaker", label="Speakers",
                      choices=names(df), selected=names(df)[4])
    return(df)
    
  })
  
  output$contents <- renderTable({
    req(data())
  })
  
  output$plot <- renderPlot({
    req(data())
    plot <- with(data(), plotVowels(f1=get(input$f1), f2=get(input$f2),
                                var.sty.by=get(input$vowel),
                                pretty=TRUE))
    plot(plot)
  })
  
  output$stats <- renderTable({
    req(data())
    statfun <- data() %>%
      group_by(get(input$vowel)) %>%
      summarise(meanf1=mean(input$ycol),
                meanf2=mean(input$xcol),
                sdf2(sd(input$xcol)))
    statfun()
  })
})

shinyApp(ui, server)
Related