Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using fluidRow with a conditional statement

Tags:

r

shiny

The following app generates a dynamic UI based on the number of variables selected. A problem is that when the number of variables selected is odd, the app generates an extra UI that is not tied to any of the variables previously selected. I've tried include if statements within the fluidRow creation statement, essentially checking if there is a remainder and if so, I've tried to tell the app to insert a blank space, but this doesn't do the trick. Does anyone have any suggestions on how to fix the issue?

## libraries
library(tidyverse)
library(shiny)

ui <- fluidPage(
  selectInput(inputId = "var",
                 label = "vars:",
                 choices = colnames(mtcars),
                 multiple = TRUE),
  uiOutput("dynUI")
)

server <- function(input, output, session) {
  output$dynUI <- renderUI({
    row_idx <- length(input$var) %>% seq_len
    row_idx <- row_idx[row_idx %% 2 == 1]
    row_idx %>% 
      map(~fluidRow(column(width = 2, 
                           selectizeInput(inputId = paste0("var", .x), 
                                          label = paste(input$var[.x], "var:"),
                                          choices = c("this", "that"),
                                          multiple = FALSE)),
                    column(width = 2,
                           selectizeInput(inputId = paste0("var", .x + 1), 
                                          label = paste(input$var[.x + 1], "var:"),
                                          choices = c("this", "that"),
                                          multiple = FALSE))))
  })
}

shinyApp(ui, server)
like image 760
DJC Avatar asked Oct 27 '25 11:10

DJC


2 Answers

You can detect the odd variable using is.na(input$var[.x + 1]) then span it on 4 columns as in :

row_idx %>%
  map( ~ {
    if (!is.na(input$var[.x + 1]))
      fluidRow(column(
        width = 2,
        selectizeInput(
          inputId = paste0("var", .x),
          label = paste(input$var[.x], "var:"),
          choices = c("this", "that"),
          multiple = FALSE
        )
      ),
      column(
        width = 2,
        selectizeInput(
          inputId = paste0("var", .x + 1),
          label = paste(input$var[.x + 1], "var:"),
          choices = c("this", "that"),
          multiple = FALSE
        )
      ))
    else
      fluidRow(column(
        width = 4,
        selectizeInput(
          inputId = paste0("var", .x),
          label = paste(input$var[.x], "var:"),
          choices = c("this", "that"),
          multiple = FALSE
        )
      ))
  })

Result

like image 50
HubertL Avatar answered Oct 29 '25 01:10

HubertL


What about something like the following?

library(tidyverse)
library(shiny)

column2 = function(x, input) {
  column(
    width = 2,
    selectizeInput(
      inputId = paste0("var", x), 
      label = paste(input$var[x], "var:"),
      choices = c("this", "that"),
      multiple = FALSE
    )
  )
}

ui <- fluidPage(
  selectInput(inputId = "var",
              label = "vars:",
              choices = colnames(mtcars),
              multiple = TRUE),
  uiOutput("dynUI")
)

server <- function(input, output, session) {
  
  output$dynUI <- renderUI({
    row_idx <- length(input$var) %>% seq_len
    row_idx <- split(row_idx, (seq(row_idx) - 1) %/% 2)
    map(row_idx, function(x, input) fluidRow(map(x, column2, input = input)), input = input)
  })
}

shinyApp(ui, server)

EDIT:

like image 36
Tomas Capretto Avatar answered Oct 29 '25 03:10

Tomas Capretto



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!