Search code examples
rshinyshiny-server

Show class probabilities of a prediction model on Shiny


I trained a Random Forest with Caret and now with Shiny App I upload a .csv file as the test set to see the class of the uploaded test set on the App. Now I need a plot on the Shiny app to show each class probability. The code:

library(caret)
library(shiny)
library(randomForest)
data("iris")
train_control <- trainControl(method="cv", number=3,savePredictions = 
TRUE,classProbs = TRUE)
model <- train(Species~., data=iris, trControl=train_control, method="nb")
ui=fluidPage(
titlePanel("Prediction Result"),
sidebarLayout(
sidebarPanel(
fileInput('datafile', 'Choose CSV File',accept=c('text/csv','text/comma- 
separated-values,text/plain','.csv')),
     tags$hr(),
     checkboxInput('header', 'Header', TRUE),
     radioButtons('sep', 'Separator',
                  c(Comma=',',
                    Semicolon=';',
                    Tab='\t'),
                  ','),
    radioButtons('quote', 'Quote',
                  c(None='',
                    'Double Quote'='"',
                    'Single Quote'="'"),
                  '"')
 ),
  mainPanel(
     tableOutput("table1"),plotOutput("plot")
  )
  )
  )

  server=function(input, output) {
  dInput = reactive({
 in.file = input$datafile

 if (is.null(in.file))
     return(NULL)
  bw <- read.csv(in.file$datapath, header=input$header, sep=input$sep, 
  quote=input$quote)
   })
  clusters <- reactive({
  df <- dInput()
  if (is.null(df))
  return(NULL)
  tt <- as.data.frame(predict(model,df))
  tt
   })
  output$table1 <- renderTable({
  toprint = clusters()
 head(toprint)
 output$plot<-renderPlot({ plot(predict(model,df,type="raw"))
 })

 })
 }
shinyApp(ui=ui,server=server)

however I get the following error:

 no applicable method for 'xtable' applied to an object of class "function"

how should I fix this error? the set set can be the following dataframe in the form of .csv:

 structure(list(Sepal.Length = 4L, Sepal.Width = 4L, Petal.Length = 1L, 
Petal.Width = 0.2, Species = structure(1L, .Label = "setosa", class = 
"factor")), class = "data.frame", row.names = c(NA, 
-1L))

Solution

  • I hope this helps you:

    First, you code is somewhat messed up here:

     output$table1 <- renderTable({
      toprint = clusters()
     head(toprint)
     output$plot<-renderPlot({ plot(predict(model,df,type="raw"))
     })
    
     })
    

    You nested output$plot inside output$table1. THe right way will be:

      output$table1 <- renderTable({
        toprint = clusters()
        head(toprint)
      })
        output$plot<-renderPlot({ plot(predict(model,df,type="raw"))
    
    
      })
    

    Second, because you require input some files before generating df, when you run the code it is empty.

    Lest say you assign at the very begining df as iris, then your code will work:

    library(caret)
    library(shiny)
    library(randomForest)
    data("iris")
    df <- NULL
    train_control <- trainControl(method="cv", number=3,savePredictions = 
                                    TRUE,classProbs = TRUE)
    model <- train(Species~., data=iris, trControl=train_control, method="nb")
    ui=fluidPage(
      titlePanel("Prediction Result"),
      sidebarLayout(
        sidebarPanel(
          fileInput('datafile', 'Choose CSV File',accept=c('text/csv','text/comma- 
                                                           separated-values,text/plain','.csv')),
          tags$hr(),
          checkboxInput('header', 'Header', TRUE),
          radioButtons('sep', 'Separator',
                       c(Comma=',',
                         Semicolon=';',
                         Tab='\t'),
                       ','),
          radioButtons('quote', 'Quote',
                       c(None='',
                         'Double Quote'='"',
                         'Single Quote'="'"),
                       '"')
          ),
        mainPanel(
          tableOutput("table1"),plotOutput("plot")
        )
      )
    )
    
    server=function(input, output) {
      dInput = reactive({
        in.file = input$datafile
    
        if (is.null(in.file))
          return(NULL)
        bw <- read.csv(in.file$datapath, header=input$header, sep=input$sep, 
                       quote=input$quote)
      })
      clusters <- reactive({
        df <- dInput()
        if (is.null(df))
          return(NULL)
        tt <- as.data.frame(predict(model,df))
        tt
      })
      output$table1 <- renderTable({
        toprint = clusters()
        head(toprint)
      })
      output$plot<-renderPlot({
        if (is.null(df))
          return(NULL)
        plot(predict(model,df,type="prob"))
    
    
      })
    }
    shinyApp(ui=ui,server=server)
    

    Of course, you need to figure out what do you show at the very beginning: nothing? a default dataset?

    Best!