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.
@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.