0

I am trying to generate a shiny app that allows a user to select a dependent and independent variable and then displays a table with the results. This is what I have:


rule <- c("bb_rule", "pp_rule", "cb_rule")
dependent <- c("inning_fr", "innings_se", "inning_rain")

ui <- navbarPage(theme = shinytheme("simplex"), "App", 


                 tabPanel("Regression Results",
                          fluidPage(
                            h3("Have Rule Changes Transformed ODI Cricket?"),
                            tableOutput("regression"),
                            sidebarPanel(
                              selectInput("depInput", "Dependent Variable",
                                        choices=dependent),
                              selectInput("ruleInput", "Rule",
                                          choices=rule)
                              )
                          )) 
    )

server <- function(input, output) {

  load("./data/data.RData")

output$regression <-
    renderTable({
      data %>% 
        lm(input$depInput ~ input$ruleInput, data = .) %>%
        tidy(conf.int=TRUE) %>% 
        select(Variable = term,
               Estimate = estimate,
               `Lower Bound` = conf.low,
               `Upper Bound` = conf.high) %>%
        gt() %>% 
        tab_header(title = "Effect of Hours on Reported Approval Rating",
                   subtitle = "Data from TWT Archive")})

    })

}


shinyApp(ui = ui, server = server)

Unfortunately, this isn't working and I get an error that Error: contrasts can be applied only to factors with 2 or more levels

However, if I directly input the variable names in the server, everything works just fine. It seems to be a problem of shiny not being able to use the input in the regression model.

HAK
  • 65
  • 5
  • It means that you are inputting an independent variable that has 1 distinct value or are NA. See answer here: https://stackoverflow.com/questions/18171246/error-in-contrasts-when-defining-a-linear-model-in-r – Phil May 03 '20 at 18:57
  • I have checked the data, that is not the case. Also, if I replace input$depInput and input$ruleInput with the actual variable names then it works fine. I would think the problem is probably with shiny not reading the input as a variable. I am not sure how to fix this, however. – HAK May 03 '20 at 18:59
  • What if you try with `lm(!! sym(input$depInput) ~ !! sym(input$ruleInput), data = .)`? – Phil May 03 '20 at 19:12
  • I then get the error: ```cannot coerce class ‘"formula"’ to a data.frame``` – HAK May 03 '20 at 19:14
  • Remove the pipe for the model. For example, `fit <- lm(..., data = data)` and then `tidy(fit, conf.int = TRUE) %>% ...` – Phil May 03 '20 at 19:17

1 Answers1

0

@phil comments on getting this to work are correct. But I feel a bit more context is needed.

Normally, we run lm with unquoted variable names:

lm(formula= Sepal.Width ~ Sepal.Length, data = iris)

But input$rule and input$dep evaluate to character. So in effect, the code is asking shiny to execute:

lm(formula= "Sepal.Width" ~ "Sepal.Length", data = iris)

which will result in error. To use the shiny inputs in lm we have to convert to symbol (sym), and then force early evaluation (!!), like @phil showed.

teofil
  • 2,344
  • 1
  • 8
  • 17