I am new to R Shiny, and am writing an app to analyze data and produce graphs based on user inputs. However, I am getting the following error code:
Error: No variable named input$column2 in the reference grid
This error comes up when I ask the user to select two options at the end of the program.
How can I fix this error and produce both of these graphs? At the moment, I just have one if
statement, but there will be more later on. Here is the dataset I am working with:
data <- data.frame(rep = c(1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
3,
3,
3,
3,
3,
3,
3,
3,
3,
3,
3,
3),
genotype = c('a',
'a',
'a',
'a',
'b',
'b',
'b',
'b',
'c',
'c',
'c',
'c',
'a',
'a',
'a',
'a',
'b',
'b',
'b',
'b',
'c',
'c',
'c',
'c',
'a',
'a',
'a',
'a',
'b',
'b',
'b',
'b',
'c',
'c',
'c',
'c'),
rate = c('1x',
'2x',
'4x',
'8x',
'1x',
'2x',
'4x',
'8x',
'1x',
'2x',
'4x',
'8x',
'1x',
'2x',
'4x',
'8x',
'1x',
'2x',
'4x',
'8x',
'1x',
'2x',
'4x',
'8x',
'1x',
'2x',
'4x',
'8x',
'1x',
'2x',
'4x',
'8x',
'1x',
'2x',
'4x',
'8x'),
ndvi = c(0.584947811,
0.642112121,
0.654116902,
0.785068313,
0.79665163,
0.674549249,
0.958911611,
0.547077528,
0.613315552,
0.768646411,
0.97107949,
0.680942649,
0.520576242,
0.723920266,
0.868779972,
0.834257732,
0.554506685,
0.520458208,
0.617282262,
0.80128067,
0.875192693,
0.572153151,
0.850305042,
0.500760522,
0.796305833,
0.643719779,
0.590512435,
0.522884966,
0.905197544,
0.663792758,
0.690415735,
0.975449466,
0.621379163,
0.734904647,
0.812023395,
0.928144532))
Here is my code for the Shiny application:
library(pacman)
p_load(shiny,
ggplot2,
readxl,
tidyverse,
car,
lmerTest,
emmeans,
glmmTMB,
DHARMa,
lme4,
rlang)
ui <- fluidPage(
fileInput("file1", "Choose .csv or .xlsx file",
accept = c("text/csv",
"text/comma-separated-values",
".csv",
".xlsx")),
textOutput("data_info"),
verbatimTextOutput("data_head"),
uiOutput("column_selector_1"),
uiOutput("column_selector_2"),
uiOutput("column_selector_3"),
uiOutput("column_selector_4"),
textOutput("dist_info"),
plotOutput("dist"),
textOutput("str_info"),
verbatimTextOutput("selected_columns"),
textOutput("two_way_anova"),
verbatimTextOutput("model_summary"),
textOutput("main_effects"),
verbatimTextOutput("model_summary_ME"),
textOutput("mod_diagnostic"),
plotOutput("diagnostic_plot"),
uiOutput("graph"),
uiOutput("model_selection"),
plotOutput("graph_plot")
)
server <- function(input, output, session) {
# Open file
req(data <- reactive({
infile <- input$file1
if (is.null(infile)) {
return(NULL)
}
read.csv(infile$datapath, header = TRUE)
}))
# Preview data
output$data_info <- renderText({
req(data())
"Preview of the data uploaded:"
})
output$data_head <- renderPrint({
req(data())
head(data(), 20)
})
# Select response variable
output$column_selector_1 <- renderUI({
req(data())
selectInput("column1","Select response variable", choices = names(data()))
})
# Select first independent variable
output$column_selector_2 <- renderUI({
req(data())
selectInput("column2", "Select first independent variable", choices = names(data()))
})
# Select second independent variable
output$column_selector_3 <- renderUI({
req(data())
selectInput("column3", "Select second independent variable", choices = names(data()))
})
# Select random variable
output$column_selector_4 <- renderUI({
req(data())
selectInput("column4", "Select random variable", choices = names(data()))
})
# Assigning user inputs to correct variables
selected_columns <- reactive({
req(data(), input$column1, input$column2, input$column3, input$column4)
list(
dependent = data()[[input$column1]],
independent1 = as.factor(data()[[input$column2]]),
independent2 = as.factor(data()[[input$column3]]),
random = as.factor(data()[[input$column4]])
)
})
# Instructional text
output$dist_info <- renderText({
req(data())
"The graph below shows the shape of response variable distribution"
})
# Distribution plot
output$dist <- renderPlot({
req(selected_columns())
cols <- selected_columns()
plot(density(cols$dependent), main = "Distribution Plot")
})
# Instructional text
output$str_info <- renderText({
req(data())
"The code below verifies that our data are in the correct structure for ANOVA analyses. All independent variables should be changed to 'Factor'. "
})
# Verifies that columns are in the correct structure
output$selected_columns <- renderPrint({
cols <- selected_columns()
str(cols)
})
# Instructional text
output$two_way_anova <- renderText({
req(data())
"Two-way ANOVA with interaction"
})
# Build ANOVA model with two-way interaction
interaction_model <- reactive({
cols <- selected_columns()
req(cols)
data <- data()
data$dep <- cols$dependent
data$indep1 <- cols$independent1
data$indep2 <- cols$independent2
data$rand <- cols$random
lmer(dep ~ indep1 * indep2 + (1|rand), data = data)
})
# Run two-way ANOVA model with interaction
output$model_summary <- renderPrint({
req(interaction_model())
Anova(interaction_model(), type = c("III"))
})
# Build main effects ANOVA model
main_effects_model <- reactive({
cols <- selected_columns()
req(cols)
data <- data()
data$dep <- cols$dependent
data$indep1 <- cols$independent1
data$indep2 <- cols$independent2
data$rand <- cols$random
lmer(dep ~ indep1 + indep2 + (1|rand), data = data)
})
# Instructional text
output$main_effects <- renderText({
req(data())
"Two-way ANOVA, main effects"
})
# Run two-way main effects model
output$model_summary_ME <- renderPrint({
req(main_effects_model())
Anova(main_effects_model(), type = c("III"))
})
output$mod_diagnostic <- renderText({
req(main_effects_model())
"Below, the `DHARMa` package is used to check model assumptions. If assumptions are not met, then data transformations may be needed before proceeding."
})
output$diagnostic_plot <- renderPlot({
req(interaction_model())
plotQQunif(interaction_model())
})
output$graph <- renderUI({
req(data(), input$column2, input$column3)
selectInput("graph", "Which variable would you like to graph?", choices = c(input$column2, input$column3, "interaction"))
})
output$model_selection <- renderUI({
req(main_effects_model(), interaction_model())
selectInput("model_selection", "Which ANOVA model do you want to graph?", choices = c("Main effects model", "Interaction model"))
})
# Create a reactive expression to store the selected graph variable
selected_graph <- reactive({
input$graph
})
# Create a reactive expression to store the selected model
selected_model <- reactive({
input$model_selection
})
# Render the plot based on the selected variables
output$graph_plot <- renderPlot({
req(data(), selected_graph(), selected_model())
if (selected_graph() == input$column2 | selected_model() == "Main effects model") {
# Mean separation: First column
mod_means_cotr1 <- emmeans(main_effects_model(), pairwise ~ input$column2,
adjust = 'tukey',
type = 'response')
mod_means1 <- multcomp::cld(object = mod_means_cotr1$emmeans,
LETTERS = "letters")
# Graph: First column
ggplot(mod_means1, aes(x = '!!sym(input$column2)', y = '!!sym(nput$column1)'))+
geom_bar(stat="identity", width = 0.6, position = "dodge", col = "black", fill = "purple3")+
geom_errorbar(aes(ymin = emmean, ymax = emmean + SE), width = 0.3, position = position_dodge(0.6))+
xlab('!!sym(input$column2)')+
ylab('!!sym(input$column1)')+
theme(plot.title=element_text(hjust=0.5, size = 20),
plot.subtitle = element_text(hjust = 0.5, size = 15),
axis.text = element_text(size = 17),
axis.title = element_text(size = 20))+
geom_text(aes(label=.group, y=emmean + SE), vjust = -0.9, size = 8) +
#ylim(0, 105)+
scale_x_discrete(labels = function(x) str_wrap(x, width = 7))
# Mean separation: Second column
mod_means_cotr2 <- emmeans(main_effects_model(), pairwise ~ input$column3,
adjust = 'tukey',
type = 'response')
mod_means2 <- multcomp::cld(object = mod_means_cotr2$emmeans,
LETTERS = "letters")
# Graph: Second column
ggplot(mod_means2, aes(x = '!!sym(input$column3)', y = '!!sym(input$column1)'))+
geom_bar(stat="identity", width = 0.6, position = "dodge", col = "black", fill = "white")+
geom_errorbar(aes(ymin = emmean, ymax = emmean + SE), width = 0.3, position = position_dodge(0.6))+
xlab('!!sym(input$column3)')+
ylab('!!sym(input$column1)')+
theme(plot.title=element_text(hjust=0.5, size = 20),
plot.subtitle = element_text(hjust = 0.5, size = 15),
axis.text = element_text(size = 17),
axis.title = element_text(size = 20))+
geom_text(aes(label=.group, y=emmean + SE), vjust = -0.9, size = 8) +
#ylim(0, 105)+
scale_x_discrete(labels = function(x) str_wrap(x, width = 7))
}
})
}
shinyApp(ui, server)