Harry Harry - 3 months ago 48
R Question

Shiny app for prediction with rpart displaying error

I tried to build a shiny app. The objective was to let user input a csv file in a input box. Then user can input a dependent variable name in text box. The main panel will display the summary details of model fit and plot.

I have coded the following as ui.R:

library(shiny)
shinyUI(fluidPage(

titlePanel(h1("ANALYSIS",align = "center")),
sidebarLayout(
sidebarPanel(

fileInput('file1', 'Select CSV File',
accept=c('text/csv',
'text/comma-separated-values,text/plain',
'.csv')),
textInput("text", label = strong("Dependent Variable"),
value = "Enter Dependent Variable...")
),
mainPanel(br(),

textOutput('text1'),
plotOutput('plot')
)
)
))


The following as server.R :

library(shiny)
library(rpart)
library(rpart.plot)

shinyServer(function(input, output) {

output$text1 <- renderText({
inFile <- input$file1
if (is.null(inFile))
return(NULL)
data <-read.csv(inFile$datapath, header=input$header, sep=input$sep, quote=input$quote)
depVar <- input$text
modrpart <- rpart(depVar ~. ,data=data)
modrpart
#depVar


})

output$plot <- renderPlot({
inFile <- input$file1
if (is.null(inFile))
return(NULL)
data <-read.csv(inFile$datapath, header=input$header, sep=input$sep, quote=input$quote)
depVar <- input$text
modrpart <- rpart(depVar ~. ,data=data)
prp(modrpart)
})


})


When RunApp is called, its showing error "Error in !: invalid argument type".
The model details and plot is not displayed in main panel as intended. I am missing something . I have used https://drive.google.com/open?id=0B0ByEpXfdtGWMjZHUGpNc3ZZSTg for test. Thanks

Answer

First of all, I created a reactive dataset data in which there is a requirement that the dataset is uploaded req(inFile). It will prevent error propagation due to missing inputs.

data <- reactive({
    inFile <- input$file1
    req(inFile)
    data <- read.csv(inFile$datapath, header=input$header, sep=input$sep,  quote=input$quote)
    data
  })

After that I created another reactive for your model with a requirement that the inputed name of the dependent variable is a valid variable. Since input$text is a string, you have to create a formula with paste0 and as.formula functions to be able to train the model. You also pass your reactive dataset via data() to the model. (These two reactives allow you to not repeat the code unnecessarily)

model <- reactive({
    req(input$text %in% names(data() ))
    depVar <- input$text
    mod <- as.formula(paste0(depVar, " ~ ."))
    modrpart <- rpart(mod, data = data() )
    modrpart
  })

Finally, you can pass the model via model() to render* functions.

Note that I changed renderText to renderPrint otherwise it would yield an error. (renderText cannot handle "cat" function)


You got this error: "Error in !: invalid argument type" because you had missing widgets and there was no input$header and few others. I fixed it by adding them. (this simple upload interface is taken from here

read.csv(inFile$datapath, header=input$header, sep=input$sep, quote=input$quote)


Full example:

library(shiny)
library(rpart)
library(rpart.plot)

server <- shinyServer(function(input, output) {

  data <- reactive({
    inFile <- input$file1
    req(inFile)
    data <- read.csv(inFile$datapath, header=input$header, sep=input$sep,  quote=input$quote)
    data
  })

  model <- reactive({
    req(input$text %in% names(data() ))
    depVar <- input$text
    mod <- as.formula(paste0(depVar, " ~ ."))
    modrpart <- rpart(mod, data = data() )
    modrpart
  })

  output$text1 <- renderPrint({ # changed to renderPrint
    model()
  })

  output$plot <- renderPlot({
    prp(model() )
  })



})


ui <- shinyUI(fluidPage(

  titlePanel(h1("ANALYSIS",align = "center")),
  sidebarLayout(
    sidebarPanel(

      fileInput('file1', 'Select 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'="'"),
                   '"'),
      br(),
      textInput("text", label = strong("Dependent Variable"), 
                value = "Enter Dependent Variable...")

    ),
    mainPanel(
      br(),
      textOutput('text1'),
      plotOutput('plot')
    )
  )
))

shinyApp(ui, server)