0

I am creating a shiny app to allow the user to upload a CSV, select a dependent and independent variable(s) and then perform a regression analysis. So far I have been able to upload the file, and select the columns of interest based on this answer. But the app is not being able to construct the lm model. The purpose is to first generate and display lm results by using the summary and then produce some plots. How can I allow the user to perform a simple regression analysis? The sample file can be downloaded from here.

UI

ui = navbarPage(tabPanel("Regression Analysis,
                         dataTableOutput('mytable'),
                         sidebarLayout(sidebarPanel(fileInput("file1", "Please choose a CSV file",
                                                              multiple = T,
                                                              accept = c("text/csv",
                                                                         "text/comma-separated-values,text/plain",
                                                                         ".csv")),
                                                    tags$hr(),
                                                    checkboxInput("header", "Header", TRUE),
                                                    radioButtons("sep", "Separator",
                                                                 choices = c(Comma = ",",
                                                                             Semicolon = ";",
                                                                             Tab = "\t"),
                                                                 selected = ","),
                                                    radioButtons("quote", "Quote",
                                                                 choices = c(None = "",
                                                                             "Double Quote" = '"',
                                                                             "Single Quote" = "'"),
                                                                 selected = '"'),
                                                    tags$hr(),
                                                    radioButtons("disp", "Display",
                                                                 choices = c(Head = "head",
                                                                             All = "all"),
                                                                 selected = "head")
                                                    
                         ),
                         mainPanel(
                           tableOutput("contents")),),
                         actionButton("choice", "Define Regression Variables"),
                         selectInput("dependent", "Dependent Variable:", choices = NULL, multiple = F),
                selectInput("independent1", "Independent Variable:", choices = NULL, multiple = F),
                selectInput("independent2", "Independent Variable:", choices = NULL, multiple = F),
                tableOutput("Table_selected.col"),
                textOutput("regTab")
))

Server

# Tell the server how to assemble inputs into outputs
server = function(input, output, session) {
  
  mydf <- reactive({
    # input$file1 will be NULL initially. After the user selects
    # and uploads a file, head of that data file by default,
    # or all rows if selected, will be shown.
    
    req(input$file1)
    
    df = read.csv(input$file1$datapath,
                  header = input$header,
                  sep = input$sep,
                  quote = input$quote)
    
    if(input$disp == "head") {
      return(head(df))
    }
    else {
      return(df)
    }
    
  })
  
  output$contents = renderTable({
    req(mydf())
    mydf()
  })
  
  # Code for allowing the user to select the variables/columns of interest 
  info <- eventReactive(input$choice, {
    req(mydf())
    f <- mydf()
    f
  })
  
  observeEvent(input$choice, {  ## to update only when you click on the actionButton
  #observe({
    req(mydf())
    updateSelectInput(session,"dependent", "Please Select a Dependent Variable:", choices = names(mydf()))
            updateSelectInput(session,"independent1", "Please Select a Independent Variable:", choices = names(mydf()))
            updateSelectInput(session,"independent2", "Please Select a Independent Variable:", choices = names(mydf()))
            
  })
  
  
  output$Table_selected.col <- renderTable({
    input$choice
    req(info(),input$columns)
    f = info()
    f = subset(f, select = input$columns) #subsetting takes place here
    head(f)
  })

output$independent1 = renderUI({
            req(mydf())
            checkboxGroupInput("independent1", "Independent Variable:",names(mydf())[!names(mydf()) %in% input$dependent],names(mydf())[!names(mydf()) %in% input$dependent])
        })
        
        output$independent2 = renderUI({
            req(mydf())
            checkboxGroupInput("independent2", "Independent Variable:",names(mydf())[!names(mydf()) %in% input$dependent],names(mydf())[!names(mydf()) %in% input$dependent])
        })
        
        runRegression = reactive({
            req(mydf())
            Model.2 = lm(as.formula(paste(input$dependent," ~ ",paste(input$independent1,collapse="+"),"+",paste(input$independent2,collapse="+"))),data=mydf())
            Model.2
            })
        
        output$regTab = renderPrint({
            if(!is.null(input$independent)){
                summary(runRegression())
            } else {
                print(data.frame(Warning="Please select Model Parameters."))
            } 
        })
}

shinyApp(ui, server)

UPDATE

After following the answer below, I am now getting new errors.

ui = navbarPage(tabPanel("Regression Analysis,
                         dataTableOutput('mytable'),
                         sidebarLayout(sidebarPanel(fileInput("file1", "Please choose a CSV file",
                                                              multiple = T,
                                                              accept = c("text/csv",
                                                                         "text/comma-separated-values,text/plain",
                                                                         ".csv")),
                                                    tags$hr(),
                                                    checkboxInput("header", "Header", TRUE),
                                                    radioButtons("sep", "Separator",
                                                                 choices = c(Comma = ",",
                                                                             Semicolon = ";",
                                                                             Tab = "\t"),
                                                                 selected = ","),
                                                    radioButtons("quote", "Quote",
                                                                 choices = c(None = "",
                                                                             "Double Quote" = '"',
                                                                             "Single Quote" = "'"),
                                                                 selected = '"'),
                                                    tags$hr(),
                                                    radioButtons("disp", "Display",
                                                                 choices = c(Head = "head",
                                                                             All = "all"),
                                                                 selected = "head")

                         ),
                         mainPanel(
                           tableOutput("contents")),),
                         actionButton("choice", "Define Regression Variables"),
                         selectInput("dependent", "Dependent Variable:", choices = NULL, multiple = F),
                selectInput("independent1", "Independent Variable:", choices = NULL, multiple = F),
                selectInput("independent2", "Independent Variable:", choices = NULL, multiple = F),
                uiOutput("dependent"),
                uiOutput("independent1"),
                uiOutput("independent2"),
                textOutput("regTab")
))

Server

# Tell the server how to assemble inputs into outputs
    server = function(input, output, session) {
        mydf = reactive({
            
            # input$file1 will be NULL initially. After the user selects
            # and uploads a file, head of that data file by default,
            # or all rows if selected, will be shown.
            
            req(input$file1)
            
            df = read.csv(input$file1$datapath,
                           header = input$header,
                           sep = input$sep,
                           quote = input$quote)
            
            if(input$disp == "head") {
                return(head(df))
            }
            else {
                return(df)
            }
            
        })
        
        output$contents = renderTable({
            req(mydf())
            mydf()
        })
        
        # Code for allowing the user to select the variables/columns of interest 
        info = eventReactive(input$choice, {
           req(mydf())
           f = mydf()
        })
        
        observeEvent(input$choice, { ## to update only when you click on the actionButton 
            req(mydf())
            updateSelectInput(session,"dependent", "Please Select a Dependent Variable:", choices = names(mydf()))
            updateSelectInput(session,"independent1", "Please Select an Independent Variable:", choices = names(mydf()))
            updateSelectInput(session,"independent2", "Please Select an Independent Variable:", choices = names(mydf()))
            
            })
        output$Table_selected.col = renderTable({
            input$choice
            req(info(), input$columns)
            f = info()
            f = subset(f, select = input$columns) #subsetting takes place here
            head(f)
        })
        
        output$dependent = renderUI({
            req(mydf(), input$independent1)
            radioButtons("dependent", "Dependent Variable:",choices=names(mydf())[!names(mydf()) %in% as.character(input$independent)])
        })
        
        output$independent1 = renderUI({
            req(mydf(),input$independent1)
            radioButtons("independent1", "Independent Variable:",names(mydf())[!names(mydf()) %in% input$dependent],names(mydf())[!names(mydf()) %in% input$dependent])
        })
        
        output$independent2 = renderUI({
            req(mydf(),input$independent1,input$independent2, input$dependent)
            radioButtons("independent2", "Independent Variable:",names(mydf())[!names(mydf()) %in% input$dependent],names(mydf())[!names(mydf()) %in% input$dependent])
        })
        
        runRegression = reactive({
            req(mydf(), input$independent1, input$independent2, input$dependent)
            Model.2 = lm(reformulate(input$dependent,input$independent1, input$independent2),data=mydf())
            })
        
        output$regTab = renderPrint({
            req(runRegression())
            if(!is.null(input$independent)){
                summary(runRegression())
            } else {
                print(data.frame(Warning="Please select Model Parameters."))
            } 

Errors

The last two actiobButtons for output$independent1 and output#independent2 are returning:

Warning: Error in radioButtons: The 'selected' argument must be of length 1

The lm(reformulate) line and renderPrint are

Warning: Error in !: invalid argument type

enter image description here

Ronak Shah
  • 377,200
  • 20
  • 156
  • 213
Ed_Gravy
  • 1,841
  • 2
  • 11
  • 34

1 Answers1

1

Try this

library(nnet)

ui = navbarPage(tabPanel("Regression Analysis",
                         dataTableOutput('mytable'),
                         sidebarLayout(
                           sidebarPanel(width=3, fileInput("file1", "Please choose a CSV file",
                                                              multiple = T,
                                                              accept = c("text/csv",
                                                                         "text/comma-separated-values,text/plain",
                                                                         ".csv")),
                                                    tags$hr(),
                                                    checkboxInput("header", "Header", TRUE),
                                                    radioButtons("sep", "Separator",
                                                                 choices = c(Comma = ",",
                                                                             Semicolon = ";",
                                                                             Tab = "\t"),
                                                                 selected = ","),
                                                    radioButtons("quote", "Quote",
                                                                 choices = c(None = "",
                                                                             "Double Quote" = '"',
                                                                             "Single Quote" = "'"),
                                                                 selected = '"'),
                                                    tags$hr(),
                                                    radioButtons("disp", "Display",
                                                                 choices = c(Head = "head",
                                                                             All = "all"),
                                                                 selected = "head")

                           ),

                           mainPanel(
                             tableOutput("contents"),
                             actionButton("choice", "Define Regression Variables"),
                             selectInput("independent", "Independent Variables:", choices = NULL, multiple = T),
                             uiOutput("dependent1"),
                             #tableOutput("Table_selected.col"),
                             verbatimTextOutput("regTab")
                           )
                         ),

))

server = function(input, output, session) {

  mydf <- reactive({
    # input$file1 will be NULL initially. After the user selects
    # and uploads a file, head of that data file by default,
    # or all rows if selected, will be shown.

    req(input$file1)

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

    if(input$disp == "head") {
      return(head(df))
    }
    else {
      return(df)
    }

  })

  output$contents = renderTable({
    req(mydf())
    mydf()
  })

  # Code for allowing the user to select the variables/columns of interest
  info <- eventReactive(input$choice, {
    req(mydf())
    f <- mydf()
    f
  })

  observeEvent(input$choice, {  ## to update only when you click on the actionButton
    req(info())
    updateSelectInput(session,"independent", "Please Select independent Variable(s):", choices = names(info()) )
  })


  # output$Table_selected.col <- renderTable({
  #   input$choice
  #   req(info(),input$columns)
  #   f = info()
  #   f = subset(f, select = input$columns) #subsetting takes place here
  #   head(f)
  # })

  output$dependent1 = renderUI({
    req(mydf(),input$independent)
    radioButtons("dependent1", "Select a dependent Variable:",choices=names(mydf())[!names(mydf()) %in% input$independent])
  })

  ###  need to build your formuila correctly; It will work with multiple independent variables
  ###  model <- reactive({lm(reformulate(input$IndVar, input$DepVar), data = RegData)})

  runRegression <- reactive({
    req(mydf(),input$independent,input$dependent1)
    lm(reformulate(input$independent, input$dependent1), data=mydf())
    # multinom(reformulate(input$independent, input$dependent1), data=mydf())  ### mulitnomial from nnet package
  })

  output$regTab = renderPrint({
    req(runRegression())
    if(!is.null(input$independent)){
      summary(runRegression())
    } else {
      print(data.frame(Warning="Please select Model Parameters."))
    }
  })

}

shinyApp(ui, server)

output

YBS
  • 19,324
  • 2
  • 9
  • 27
  • Why are there two dependent (dependent 1 and dependent2) variables in the code? Actually, the lm formula that I am using is something like this lm(dependent ~ independent1 + independent2). I am sorry if my question wasn't clear on this. – Ed_Gravy Apr 26 '21 at 03:42
  • I am getting new errors now, so I am updating the question to include those errors too. – Ed_Gravy Apr 26 '21 at 05:12
  • I have also uploaded a sample file to make the code reproducible. – Ed_Gravy Apr 26 '21 at 05:27
  • 1
    Please try the updated code. It has been adjusted to select multiple independent variables. – YBS Apr 26 '21 at 13:38
  • Thank you, the code works fine now but the results are not correct, you see when you do lm(formula = SWE ~ Mean.Z + Intensity.mean, data = Mean_SWE) I get this https://app.box.com/s/1ci67nx1hfjb1ynhv0jrid9rae0tww0u. And as you can see the results are quite different, so maybe the lm formula in the shiny app code needs to be fixed. – Ed_Gravy Apr 26 '21 at 21:18
  • 1
    Yes, you can change the formula or use mulitnom from nnet package or some other package. Also, please ensure that you are looking at the whole dataset not just head (first 6 records). – YBS Apr 26 '21 at 21:24
  • Thank you, this worked, so now I have posted a new question where now I am going to the next step in the app where now based on the lm model, interactive regression plots will be created using autoplot and autoplotly using the ggfortify package. Since you are familiar with the code and sample data, can you please look at it?https://stackoverflow.com/questions/67274572/using-autoplotly-in-shiny-app-with-user-selected-columns – Ed_Gravy Apr 26 '21 at 22:31