Home > Software engineering >  No output from for loop eventReactive: Shiny
No output from for loop eventReactive: Shiny

Time:06-06

Awesome people out there! Need a quick help on Shiny eventReactive().

I have two data frames (df1, df2), which are outputs of previous calculations in my Shiny app. I need to run a for loop on these two data frames in my Shiny app with eventReactive(). When I click/trigger the actionButton("simulate") from my UI. I need to run the below for loop and create a data table in Shiny app. The problem I have is I do not see anything happen on UI, UI is blank (while I expect to see a datatable) and there is no error message to debug.

The for loop runs fine in console but not in the Shiny App. I tried lapply but that did not work as well. It was also an empty screen without any output.

Any help is much Appreciated!

For loop in console, this runs fine

library(tidyverse)

df1 <- data.frame(Year = rep(c(2018:2020), each = 12),
                  Treatment = rep(c("AA", "BB", "CC"), each = 4, times = 3),
                  Source = rep(c("Ran", "Ban", "Dam", "Sam"), times = 9),
                  Value = sample(36))

df2 <- data.frame(Year = rep(c(2018:2020), each = 3),
                  Treatment = rep(c("AA", "BB", "CC"), times = 3),
                  Value2 = sample(9))

tnames <- unique(df1$Treatment)

simdata <- data.frame()

for(i in 1:length(tnames)){
  
  vcmp <- df1 %>% filter(Treatment == tnames[i]) %>%
    group_by(Source) %>% 
    summarise(median = median(Value)) %>%
    mutate(Trait  = tnames[i])
  
  preSD <- df2 %>% filter(Treatment == tnames[i]) %>%
    summarize(Value2 = median(Value2))
  
  simuS <- tibble(nLo = rep(5:15, times = 3), 
                  nRe = rep(1:3, each = 11),
                  nPlo = nLo * nRe, 
                  Vg = vcmp[[3,2]], 
                  Ve = vcmp[[4,2]],
                  ycept = preSD[[1,1]],
                  sm = sqrt(Vg / nLo   Ve / nPlo),
                  sd = sqrt(2 * (Vg / nLo   Ve / nPlo)),
                  ld = 2 * sd,
                  Rp = factor(nRe), 
                  Treatment = tnames[i])
  
  simdata <- rbind(simdata, simuS)
}

MRE, Shiny implementation, I kind of solved half, I can see the output now but it only generates one iteration. not the entire for loop

library(shiny)
library(tidyverse)
library(DT)

ui <- fluidPage(
  sidebarLayout(
    sidebarPanel(width = 2,
                 selectInput("Parameter", "Select Parameter","", ""),
                 actionButton("generate", "Generate Data"),
                 hr(),
                 hr(),
                 actionButton("simulate", "Simulate Data")),
    mainPanel(width = 7,
              DT::dataTableOutput("table1"),
              DT::dataTableOutput("table2"),
              DT::dataTableOutput("table3"))
  )
)

server <- function(input, output, session){
  
  table1 <- eventReactive(input$generate,{
    df1 <- data.frame(Year = rep(c(2018:2020), each = 12),
               Treatment = rep(c("AA", "BB", "CC"), each = 4, times = 3),
               Source = rep(c("Ran", "Ban", "Dam", "Sam"), times = 9),
               Value = sample(36))
  })
  
  table2 <- eventReactive(input$generate, {
    df2 <- data.frame(Year = rep(c(2018:2020), each = 3),
                      Treatment = rep(c("AA", "BB", "CC"), times = 3),
                      Value2 = sample(9))
  })
  
  simudata <- eventReactive(input$simulate,{
    tnames <- unique(table1()$Treatment)
    simudata <- tibble()
    
    for(i in 1:length(tnames)){
      
      vcmp <- table1() %>% 
        filter(Treatment == tnames[i]) %>%
        group_by(Source) %>% 
        summarise(median = median(Value)) %>%
        mutate(Trait  = tnames[i])
      
      preSD <- table2() %>% 
        filter(Treatment == tnames[i]) %>%
        summarize(Value2 = median(Value2))
      
      new_Row <- tibble(nLo = rep(5:15, times = 3),
                      nRe = rep(1:3, each = 11),
                      nPlo = nLo * nRe, 
                      Vg = vcmp[[3,2]], 
                      Ve = vcmp[[4,2]],
                      ycept = preSD[[1,1]],
                      sm = sqrt(Vg / nLo   Ve / nPlo),
                      sd = sqrt(2 * (Vg / nLo   Ve / nPlo)),
                      ld = 2 * sd,
                      Rp = factor(nRe), 
                      Treatment = tnames[i])
      
      simudata <- rbind(simudata, new_Row)
      return(simudata)
      }
    })
  
  output$table1 <- DT::renderDataTable(table1(), options = list(paging = t, pageLength = 5))
  output$table2 <- DT::renderDataTable(table2(), options = list(paging = t, pageLength = 5))
  output$table3 <- DT::renderDataTable(simudata(), options = list(paging = t, pageLength = 5))
}

shinyApp(ui, server)


CodePudding user response:

You can address your issue by using local() as shown below.

simudata <- eventReactive(input$simulate,{
    tnames <- unique(table1()$Treatment)
    simudata <- tibble()
    
    for(i in 1:length(tnames)){
      local({
        i <- i
        vcmp <- table1() %>% 
          dplyr::filter(Treatment == tnames[i]) %>%
          group_by(Source) %>% 
          dplyr::summarise(median = median(Value)) %>%
          dplyr::mutate(Trait  = tnames[i])
        
        preSD <- table2() %>% 
          dplyr::filter(Treatment == tnames[i]) %>%
          dplyr::summarize(Value2 = median(Value2))
        
        new_Row <- tibble(nLo = rep(5:15, times = 3),
                          nRe = rep(1:3, each = 11),
                          nPlo = nLo * nRe, 
                          Vg = vcmp[[3,2]], 
                          Ve = vcmp[[4,2]],
                          ycept = preSD[[1,1]],
                          sm = sqrt(Vg / nLo   Ve / nPlo),
                          sd = sqrt(2 * (Vg / nLo   Ve / nPlo)),
                          ld = 2 * sd,
                          Rp = factor(nRe), 
                          Treatment = tnames[i])
        
        simudata <<- rbind(simudata, new_Row)
      })
      
    }
    return(simudata)
  })
  • Related