I'm developing a shiny app where the user will be able to describe the room occupancy of multiple houses. The main idea of the code is to input the number of houses (inputId = 'n_houses'
), i.e. the number of tabs in the mainPanel
is equal to the number of houses inputed. Each house tab should be connected to a different sidebarPanel
, i.e. when accessing the house tab in the mainPanel
, the correspondent sidebarPanel
is displayed. In the sidebarPanel
, the number of rooms (inputId = 'n_rooms'
) of the correspondent house tab is inputed. Finally, each room is inputed with an occupancy value (inputId = 'occup'
), that can be either 'liv' (living room) or 'dorm' (dormitory).
Each mainPanel
tab should display the occupancy of all its correspondent rooms.
A simple example of the inputs follows:
- n_houses = 2 (two houses)
- n_rooms1 = 2 (two rooms in the first house) - 2.a. occup11 = 'liv' (living room); 2.b. occup12 = 'dorm' (dormitory)
- n_rooms2 = 3 (three rooms in the second house) - 3.a. occup21 = 'dorm' (dormitory); 3.b. occup22 = 'liv' (living room); 3.c. occup23 = 'dorm' (dormitory) Ps.: it sums a total of 5 room occupancies.
Then, the outputs should be:
- mainPanel tab 1 (house 1): 'Results for house 1: liv dorm dorm'
- mainPanel tab 2 (house 2): 'Results for house 2: liv dorm'
The code chunk below shows my last efforts to solve this issue.
# shiny user interface
ui = shinyUI(
fluidPage(
headerPanel(
h1('ROOMS OCCUPANCY', align = 'center')
),
sidebarPanel(
sliderInput(
inputId = 'n_rooms',
label = 'Choose the number of rooms in the correspondet house:',
min = 2, max = 5, step = 1, value = 3
),
uiOutput('rooms')
),
mainPanel(
sliderInput(
inputId = 'n_houses',
label = 'Choose the number of houses:',
min = 1, max = 20, step = 1, value = 1
),
uiOutput('houses')
)
)
)
# auxiliar functions to shiny server
# generate room tab panel
GenRoomTab = function(ind_room, ind_house) {
panel = tabPanel(
title = paste('Room', ind_room),
value = paste0(ind_house, ind_room),
radioButtons(
inputId = paste0('occup', ind_house, ind_room),
label = 'Room occupancy:',
choices = list('Living room' = paste0('liv', ind_house, ind_room),
'Dormitory' = paste0('dorm', ind_house, ind_room)),
selected = paste0('liv', ind_house, ind_room)
)
)
return(panel)
}
# generate room tabset panel
GenRoomTabset = function(ind_house, n_rooms) {
tab_panels = lapply(1:n_rooms, GenRoomTab, ind_house)
tabset_panel = do.call(tabsetPanel, tab_panels)
condition_panel = list(condition = paste('input.tabselected ==', ind_house), tabset_panel)
return(condition_panel)
}
# generate house tab panel
GenHouseTab = function(ind_house) {
panel = tabPanel(
title = paste('House', ind_house),
value = ind_house,
h4(paste('Results for house', ind_house, ':'))
)
return(panel)
}
# generate summary tab panel
GenSummTab = function() {
panel = tabPanel(
title = 'Summary'
)
return(list(panel))
}
# shiny server
server = shinyServer(
function(input, output) {
# define room tabset panels
output$rooms = renderUI({
room_tabsets = do.call(GenRoomTabset, list(1:input$n_houses, input$n_rooms))
do.call(conditionalPanel, room_tabsets)
})
# define house tab panels
output$houses = renderUI({
house_tab_panels = lapply(1:input$n_houses, GenHouseTab)
summ_tab_panel = GenSummTab()
tab_panels = c(list(type = 'tab', id = 'tabselected'),
house_tab_panels, summ_tab_panel)
do.call(tabsetPanel, tab_panels)
})
}
)
# associate ui to server
shinyApp(ui = ui, server = server)
When I run this code the following warning message shows up:
Warning: Error in radioButtons: The 'selected' argument must be of length 1 105: stop 104: radioButtons 100: FUN [/home/rodox/git/giz/app/app.r#29] 99: lapply 98: [/home/rodox/git/giz/app/app.r#44] 96: renderUI [/home/rodox/git/giz/app/app.r#71] 95: func 82: origRenderFunc 81: output$rooms 1: runApp
I think it is related to selected = paste0('liv', ind_house, ind_room)
, inside function GenRoomTab()
. The GenRoomTab()
is applied within lapply(1:n_rooms, GenRoomTab, ind_house)
, inside the function GenRoomTabset()
. However it seems strange to me, since ind_house
is a vector as well as ind_room
.
Another difficulty that I have is to display the occupancy of all the rooms into the correspondent house tab.
I've been trying to solve this for a while, but couldn't solve it... I hope someone can save me!