Search code examples
rshinyfitdistrplus

fitdist in r shiny, error need finite 'xlim' values


I am creating my first Shiny App and I am struggling plotting the four goodness of fit test from the fitdistrplus package. (for references, I am trying to reproduce the plots from page 7 from the reference here:

https://www.jstatsoft.org/article/view/v064i04/v64i04.pdf

Briefly, I want the user to select a subset of data based on the variable M and then evaluate different probability distributions density for the variable Q. I have used the code to create the goodness of fit plots outside of Shiny and it works perfectly. In R Shiny, I am able to plot individually the fit (fw, fg, fl) but when it comes to use the denscomp, qqcomp, cdfcomp and ppcomp, I have this error message:

Error: need finite 'xlim' values

I have tried to add the xlim and ylim within the code (ex: xlim =c(0,300), ylim=c(0.008)) but still I received the error message.

Does anyone has any idea how to solve this?

My code below:

library(fitdistrplus)
library(shiny)
library(dplyr)

ui<-  shinyUI(pageWithSidebar(

headerPanel("Distribution analysis"),

sidebarPanel(
  selectInput("input1", 
              label = "M",
              choices = data$m,
              selected = "M1"),

mainPanel(
  tabsetPanel(
    tabPanel("Fit", plotOutput("fit1")), 
    tabPanel("Distribution", plotOutput("hist1")), 
    tabPanel("Table", tableOutput("table"))
))
))

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

dataInput <- reactive({
  data %>%
    filter(m==input$input1)
})

fw<- eventReactive(input$input1 {
  fitdist(dataInput()$Q, "weibull")
  })

fg<- eventReactive(input$input1 {
  fitdist(dataInput()$Q, "gamma")
  })

fln<- eventReactive(input$input1 {
  fitdist(dataInput()$Q, "lnorm")
  })

output$fit1 <- renderPlot({
  if (!is.null(dataInput())) {
   par(mfrow = c(2, 2))
   plot.legend <- c("Weibull", "lognormal", "gamma")
   denscomp(list(fw, fln, fg), legendtext = plot.legend)
   qqcomp(list(fw, fln, fg), legendtext = plot.legend)
   cdfcomp(list(fw, fln, fg), legendtext = plot.legend)
   ppcomp(list(fw, fln, fg), legendtext = plot.legend) 

    }
})
})  

shinyApp(ui=ui, server=server)  

And the data to recreate the example:

m<- c("M1","M3","M3", "M2", "M3","M2","M2","M1","M1","M1","M1","M3","M3","M2","M2","M1","M3","M3", "M3","M2","M2","M2","M1","M1","M1","M1","M1","M3","M3","M3" )
Q<- c(265, 65, 40, 245,230,175, 185, 190, 290, 85, 75, 155, 110, 60, 35, 245, 300,175, 180, 265, 55, 200, 95, 185, 165, 55, 90, 190, 235, 200) 
data<- data.frame(m,Q)

Solution

  • I fixed some thing you have, but since I am not familiar with package fitdistrplus I cannot fully debug other warnings. Note that all the reactives are functions so should be used as such e.g.: fln() and not fln

    #rm(list = ls())
    library(fitdistrplus)
    library(shiny)
    library(dplyr)
    
    m<- c("M1","M3","M3", "M2", "M3","M2","M2","M1","M1","M1","M1","M3","M3","M2","M2","M1","M3","M3", "M3","M2","M2","M2","M1","M1","M1","M1","M1","M3","M3","M3" )
    Q<- c(265, 65, 40, 245,230,175, 185, 190, 290, 85, 75, 155, 110, 60, 35, 245, 300,175, 180, 265, 55, 200, 95, 185, 165, 55, 90, 190, 235, 200) 
    data<- data.frame(m,Q)
    
    ui<-  shinyUI(pageWithSidebar(
      headerPanel("Distribution analysis"),
      sidebarPanel(  selectInput("input1", label = "M",choices = data$m,selected = "M1")),
    
      mainPanel(
        tabsetPanel(
          tabPanel("Fit", plotOutput("fit1")), 
          tabPanel("Distribution", plotOutput("hist1")), 
          tabPanel("Table", tableOutput("table"))
        ))
    ))
    
    server<- shinyServer(function(input, output) {
    
      dataInput <- reactive({
        if(is.null(input$input1)){
          return()
        }
        data %>% filter(m==input$input1)
      })
    
      fw <- eventReactive(input$input1, {
        fitdist(dataInput()$Q, "weibull")
      })
    
      fg <- eventReactive(input$input1, {
        fitdist(dataInput()$Q, "gamma")
      })
    
      fln <- eventReactive(input$input1, {
        fitdist(dataInput()$Q, "lnorm")
      })
    
      output$fit1 <- renderPlot({
        if(is.null(dataInput()) | nrow(dataInput()) ==0){
          return()
        }
        par(mfrow = c(2, 2))
        plot.legend <- c("Weibull", "lognormal", "gamma")
        denscomp(list(fw(), fln(), fg()), legendtext = plot.legend)
        qqcomp(list(fw(), fln(), fg()), legendtext = plot.legend)
        cdfcomp(list(fw(), fln(), fg()), legendtext = plot.legend)
        ppcomp(list(fw(), fln(), fg()), legendtext = plot.legend) 
      })
    })  
    
    shinyApp(ui=ui, server=server) 
    

    enter image description here

    Note of these message errors which you should take care of, possibly start here https://stats.stackexchange.com/questions/158163/why-does-this-data-throw-an-error-in-r-fitdistr

    enter image description here