[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