[R] R Shiny Help - Trouble passing user input columns to emmeans after ANOVA analysis
I B
|b@rnh@rt055 @end|ng |rom gm@||@com
Thu Jun 6 02:07:19 CEST 2024
Hello everybody,
I have experience coding with R, but am brand new to R Shiny. I am trying
to produce an application that will allow users to upload their own
dataset, select columns they want an ANOVA analysis run on, and generate
graphs that will allow users to view their results. However, I am getting
the following error: *"Argument is of length zero."*
Being new to Shiny, I am having trouble passing the user input column to an
emmeans argument in order to do a post hoc analysis, and using that
information to produce a graph. Can somebody help me with this? *The code
for my dataset and application are provided below; copying and pasting
directly into R should generate the reproducible example.*
In my application, the following columns should be selected after uploading
the dataset:
- Select response variable: "ndvi"
- Select first independent variable: "genotype"
- Select second independent variable: "rate"
- Select random variable: "rep"
For this example, the final two drop-down selections should be:
- "Which variable would you like to graph? "genotype"
- "Which ANOVA model do you want to graph? "Main effects model"
Any help would be great. Thank you so much!
Sincerely,
Isaac Barnhart, PhD
*Here is my dataset:*
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:*
library(shiny)
library(ggplot2)
library(tidyverse)
library(emmeans)
library(DHARMa)
library(lme4)
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]]),
# Define column names for later use
column1 <- input$column1,
column2 <- input$column2,
column3 <- input$column3,
column4 <- 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())
cols <- selected_columns()
if (selected_graph() == cols$column2 | selected_model() == "Main
effects model") {
# Mean separation: First column
mod_means_cotr1 <- emmeans(main_effects_model(), pairwise ~
cols$column2,
adjust = 'tukey',
type = 'response')
mod_means1 <- multcomp::cld(object = mod_means_cotr1$emmeans,
LETTERS = "letters")
# Graph: First column
ggplot(mod_means1, aes_string(x = cols$column2, y = cols_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(cols$column2)+
ylab(cols$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)
[[alternative HTML version deleted]]
More information about the R-help
mailing list