Home > Blockchain >  R SHINY - Conditional panel output shifted?
R SHINY - Conditional panel output shifted?

Time:01-24

This post is related to R shiny - Checkbox and conditional panels issues. I have here managed to create an MRE of the problem.

To sum it up again, when clicking on the second checkbox OR the first and second checkbox at the same time, the data frame output is shifted... I would like it to be displayed at the same position as it is when you click on the first checkbox.

library(shiny)
library(ggplot2)

ui <- shinyUI(fluidPage(
     
     titlePanel("Construction"),
         
         sidebarLayout(
             sidebarPanel(
                 checkboxInput("EF", "Efficient Frontier"),
                 checkboxInput("MonteCarlo", "Monte Carlo Simulation"),
                 
                 fluidRow(
                     align = "center",
                     actionButton("Gow", "Go!")),
                 
             ),
             
             mainPanel(
                 column(12,
                        br(),
                        align = "left",
                        splitLayout(cellWidths = c("70%", "30%"),
                                    plotOutput("Graphw"),
                                    conditionalPanel(condition = "input.EF == true && input.MonteCarlo == false", tableOutput("EFWeightsTable")),
                                    conditionalPanel(condition = "input.MonteCarlo == true && input.EF == false", tableOutput("MCWeightsTable")),
                                    conditionalPanel(condition = "input.MonteCarlo == true && input.EF == true", tableOutput("EFMCWeightsTable")))),
                 column(12,
                        align = "center",
                        conditionalPanel(condition = "input.EF == true && input.MonteCarlo == false", plotOutput("GraphEF")),
                        conditionalPanel(condition = "input.MonteCarlo == true && input.EF == false", plotOutput("GraphMC")),
                        conditionalPanel(condition = "input.MonteCarlo == true && input.EF == true", plotOutput("GraphEFMC"))
                 )
             )
         )
     )
)


#Server
server <- shinyServer(function(input, output) {

    OPw <- reactiveValues()
    observeEvent(input$Gow, {
        
        OPw$PC <- Run(1,2,3)
        
        if(input$EF == TRUE && input$MonteCarlo == FALSE){
            showModal(modalDialog("Loading... Please Wait", footer=NULL)) 
            OPw$LIST1 <- Run2(1,2,3)
        }
        removeModal() 
        
        if(input$MonteCarlo == TRUE && input$EF == FALSE){
            showModal(modalDialog("Loading... Please Wait", footer=NULL)) 
            OPw$LIST2 <- Run3(1,2,3)
        }
        removeModal() 
        
        if(input$MonteCarlo == TRUE && input$EF == TRUE){
            showModal(modalDialog("Loading... Please Wait", footer=NULL)) 
            OPw$LIST3 <- Run4(1,2,3)
        }
        removeModal() 
    })
    
    #Output Variables
    output$Graphw <- renderPlot({ 
        OPw$PC}, height = 400, width = 400)
    
    output$GraphEF <- renderPlot({ 
        OPw$LIST1[[1]]
    },height = 550, width = 700)
    
    output$EFWeightsTable <- renderTable({ 
        OPw$LIST1[[2]]}, colnames = TRUE
    )
    
    output$GraphMC <- renderPlot({ 
        OPw$LIST2[[1]]
    },height = 550, width = 700)
    
    output$MCWeightsTable <- renderTable({ 
        OPw$LIST2[[2]]}, colnames = TRUE
    )
    
    output$GraphEFMC <- renderPlot({ 
        OPw$LIST3[[1]]
    },height = 550, width = 700)
    
    output$EFMCWeightsTable <- renderTable({ 
        OPw$LIST3[[2]]}, colnames = TRUE
    )
    
    #FUNCTIONS
    Run <- function(a, b, c){
        
        Plot <- ggplot(as.data.frame(cbind(c(1,2,3),c(2,3,4))), aes(c(1,2,3), c(2,3,4)))  
            geom_line() 
        
        return(Plot)
    }
    
    Run2 <- function(a,b,c){
        
        eweights <- data.frame(cbind(seq(1,9),seq(1,9),seq(1,9)))
        
        MYPLOT <- ggplot(as.data.frame(cbind(c(10,7,4),c(5,6,7))), aes(c(10,7,4), c(5,6,7)))  
            geom_line() 
            
        return(list(MYPLOT, eweights))
    }
    
    Run3 <- function(a,b,c){
        
        eweights <- data.frame(cbind(seq(2,10),seq(2,10),seq(2,10)))
        
        MYPLOT <- ggplot(as.data.frame(cbind(c(4,5,6),c(7,8,9))), aes(c(4,5,6),c(7,8,9)))  
            geom_line() 
        
        return(list(MYPLOT, eweights))
    }
    
    Run4 <- function(a,b,c){
        Run3(a,b,c)
    }
})

shinyApp (ui = ui, server = server)

thank you

CodePudding user response:

Use of renderUI() should help you. Try this

library(shiny)
library(ggplot2)

ui <- shinyUI(fluidPage(
  
  titlePanel("Construction"),
  
  sidebarLayout(
    sidebarPanel(
      checkboxInput("EF", "Efficient Frontier"),
      checkboxInput("MonteCarlo", "Monte Carlo Simulation"),
      
      fluidRow(
        align = "center",
        actionButton("Gow", "Go!")),
      
    ),
    
    mainPanel(
      column(12,
             br(),
             align = "left",
             splitLayout(cellWidths = c("70%", "30%"),
                         plotOutput("Graphw"), uiOutput("mytable")
                         )),
      column(12,
             align = "center",
             conditionalPanel(condition = "input.EF == true && input.MonteCarlo == false", plotOutput("GraphEF")),
             conditionalPanel(condition = "input.MonteCarlo == true && input.EF == false", plotOutput("GraphMC")),
             conditionalPanel(condition = "input.MonteCarlo == true && input.EF == true", plotOutput("GraphEFMC"))
      )
    )
  )
)
)

#Server
server <- shinyServer(function(input, output) {
  
  OPw <- reactiveValues()
  observeEvent(input$Gow, {
    
    OPw$PC <- Run(1,2,3)
    
    if(input$EF == TRUE && input$MonteCarlo == FALSE){
      showModal(modalDialog("Loading... Please Wait 1", footer=NULL)) 
      OPw$LIST1 <- Run2(1,2,3)
    }
    removeModal() 
    
    if(input$MonteCarlo == TRUE && input$EF == FALSE){
      showModal(modalDialog("Loading... Please Wait 2", footer=NULL)) 
      OPw$LIST2 <- Run3(1,2,3)
    }
    removeModal() 
    
    if(input$MonteCarlo == TRUE && input$EF == TRUE){
      showModal(modalDialog("Loading... Please Wait 3", footer=NULL)) 
      OPw$LIST3 <- Run4(1,2,3)
    }
    removeModal() 
  })
  
  #Output Variables
  output$Graphw <- renderPlot({ 
    OPw$PC}, height = 400, width = 400)
  
  output$GraphEF <- renderPlot({ 
    OPw$LIST1[[1]]
  },height = 550, width = 700)
  
  output$EFWeightsTable <- renderTable({ 
    OPw$LIST1[[2]]}, colnames = TRUE
  )
  
  output$GraphMC <- renderPlot({ 
    OPw$LIST2[[1]]
  },height = 550, width = 700)
  
  output$MCWeightsTable <- renderTable({ 
    OPw$LIST2[[2]]}, colnames = TRUE
  )
  
  output$GraphEFMC <- renderPlot({ 
    OPw$LIST3[[1]]
  },height = 550, width = 700)
  
  output$EFMCWeightsTable <- renderTable({ 
    OPw$LIST3[[2]]}, colnames = TRUE
  )
  
  output$mytable <- renderUI({
    if (input$EF & !input$MonteCarlo) {tableOutput("EFWeightsTable")
    } else if (!input$EF & input$MonteCarlo){tableOutput("MCWeightsTable")
    } else if (input$EF & input$MonteCarlo){tableOutput("EFMCWeightsTable")
    } else return(NULL)
  })
  
  #FUNCTIONS
  Run <- function(a, b, c){
    
    Plot <- ggplot(as.data.frame(cbind(c(1,2,3),c(2,3,4))), aes(c(1,2,3), c(2,3,4)))  
      geom_line() 
    
    return(Plot)
  }
  
  Run2 <- function(a,b,c){
    
    eweights <- data.frame(cbind(seq(1,9),seq(1,9),seq(1,9)))
    
    MYPLOT <- ggplot(as.data.frame(cbind(c(10,7,4),c(5,6,7))), aes(c(10,7,4), c(5,6,7)))  
      geom_line() 
    
    return(list(MYPLOT, eweights))
  }
  
  Run3 <- function(a,b,c){
    
    eweights <- data.frame(cbind(seq(2,10),seq(2,10),seq(2,10)))
    
    MYPLOT <- ggplot(as.data.frame(cbind(c(4,5,6),c(7,8,9))), aes(c(4,5,6),c(7,8,9)))  
      geom_line() 
    
    return(list(MYPLOT, eweights))
  }
  
  Run4 <- function(a,b,c){
    Run3(a,b,c)
  }
})

shinyApp (ui = ui, server = server)

CodePudding user response:

I see you already accepted an answer but I had already put in the work. I used a list() object for the conditions and that seemed to work. You can cut down most of the server code by making simple objects as placeholders.

library(shiny)

ui <- shinyUI(fluidPage(
  sidebarLayout(
    sidebarPanel(
      checkboxInput("EF", "Efficient Frontier"),
      checkboxInput("MonteCarlo", "Monte Carlo Simulation")
    ),
    mainPanel(
      column(12, # if these are supposed to stack, I'd use `fluidRow()`
        align = "left",
        splitLayout(
          cellWidths = c("70%", "30%"),
          plotOutput("Graphw"),
          list(  # I made this a list object
            conditionalPanel(condition = "input.EF == true && input.MonteCarlo == false", tableOutput("EFWeightsTable")),
            conditionalPanel(condition = "input.MonteCarlo == true && input.EF == false", tableOutput("MCWeightsTable")),
            conditionalPanel(condition = "input.MonteCarlo == true && input.EF == true", tableOutput("EFMCWeightsTable"))
          )
        )
      ),
      column(12,
        align = "center",
        conditionalPanel(condition = "input.EF == true && input.MonteCarlo == false", plotOutput("GraphEF")),
        conditionalPanel(condition = "input.MonteCarlo == true && input.EF == false", plotOutput("GraphMC")),
        conditionalPanel(condition = "input.MonteCarlo == true && input.EF == true", plotOutput("GraphEFMC"))
      )
    )
  )
))

server <- function(input, output, session) {  
  # dummy tables
  df <- mtcars[1:3, 1:3]
  output$tablew <- renderTable(df)
  output$EFWeightsTable <- renderTable(df)
  output$MCWeightsTable <- renderTable(df)
  output$EFMCWeightsTable <- renderTable(df)
  # dummy plots
  output$GraphEF <- renderPlot(plot(1, 1, main = "Efficient Frontier"))
  output$GraphMC <- renderPlot(plot(1, 1, main = "Monte Carlo"))
  output$GraphEFMC <- renderPlot(plot(1, 1, main = "Both"))
  output$Graphw <- renderPlot(plot(1, 1, main = "Graph W"))
}

shinyApp(ui, server)

  •  Tags:  
  • Related