in R shiny, how to automatically or based on function tabPanel, given we have 3 levels of lists?

好久不见. 提交于 2020-01-20 08:32:50

问题


I need to create conditional 3 levels of tabs the first level or tabPanel includes three tabs "NUTS","SWEETS","DRINKS" so the

level1<-list(DRINKS,SWEETS,NUTS)

the second level or is conditional on the first level for example after selecting DRINKS, would be juices, energydrinks, hotdrinks the third level would be after selecting energy drinks to "powerhorse","redbull"

tried code but not working is this

lists -------------------------------------------------------------------

library(shiny)
library(reshape2)
library(dplyr)

hotdrinks<-list('hotdrinks'=list("tea","green tea")) 
juices<-list('juices'=list("orange","mango") )
energydrinks<-list('energydrinks'=list("powerhorse","redbull")) 
drinks<-list('drinks'=list(hotdrinks,juices,energydrinks))
biscuits<-list('bisc'=list("loacker","tuc"))
choc<-list('choc'=list("aftereight","lindt") )
gum<-list('gum'=list("trident","clortes") )
sweets<-list('sweets'=list(gum,juices,energydrinks))

almonds<-list('almonds'=list("salted","roasted") )
pistcio<-list('pistcio'=list("flavourd","roasted")) 
nuts<-list('nuts'=list(almonds,pistcio))

all_products<-list(sweets,nuts,drinks)
mt<-melt(all_products)

mt2<-mt%>%mutate("Price"=c(23,34,23,23,54,32,45,23,12,56,76,34,62,12,98,43),
          "Quantity"=c(10,20,26,22,51,52,45,23,12,56,76,55,62,12,98,43))

t1<-mt2[,c(5,3,1,8,7)]
t1
colnames(t1)<-c("CAT","PN","SP","Quantity","Price")

t2<-list(unique(t1$CAT))
t2

app ---------------------------------------------------------------------

library(shiny)

server <- function(input, output,session) {
  observe({print(input$t)})
  observe({print(input$u)})
  observe({print(input$v)})
  t3<-t1%>%filter(t1$CAT==input$t)
  print(t3)
  t4<-list(unique(t3$PN))
  print(t4)
  t5<-t3%>%filter(t3$PN==input$r)
  print(t5)
  t6<-list(unique(t5$SP))
  print(t6)
  t7<-reactive({
         t1%>%filter(t1$CAT==input$t,t1$PN==input$u,t1$SP==inptut$v)
         print(t7())
       })
  output$mytable <- DT::renderDataTable({
         t7
       })

  lapply(1:5, function(j) {
         DT::dataTableOutput("mytable")
       })
}

ui <- pageWithSidebar(
  headerPanel("xxx"),
  sidebarPanel(),
  mainPanel(
    do.call(tabsetPanel, c(id='t',lapply(unlist(t2), function(i) {
  tabPanel(
      do.call(tabsetPanel, c(id='u',lapply(unlist(t4), function(i) {
      tabPanel(
        do.call(tabsetPanel, c(id='v',lapply(unlist(t6), function(i) {
          tabPanel(DT::dataTableOutput("mytable")
              )
        })))

          )
        })))  

      )
    })))

  )
)
shinyApp(ui, server)

the manual steps

hotdrinks<-list("tea","green tea") 
juices<-list("orange","mango") 
energydrinks<-list("powerhorse","redbull") 
drinks<-list(hotdrinks,juices,energydrinks) 

biscuits<-list("loacker","tuc") 
choc<-list("aftereight","lindt") 
gum<-list("trident","clortes") 
sweets<-list(gum,juices,energydrinks) 

almonds<-list("salted","roasted") 
pistcio<-list("flavourd","roasted") 
nuts<-list(almonds,pistcio) 

all_products<-list(sweets,nuts,drinks)

choc<-  
tabsetPanel(
tabPanel("aftereight"),
tabPanel("lindt")
)
bisc<-  
tabsetPanel(
tabPanel("loacker"),
tabPanel("tuc")
)
gm<-  
tabsetPanel(
tabPanel("trident"),
tabPanel("clortes")
)

hdrinks<-  
tabsetPanel(
tabPanel("tea"),
tabPanel("green tea")
)
jcs<-  
tabsetPanel(
tabPanel("orange"),
tabPanel("mango")
)
ngdrinks<-  
tabsetPanel(
tabPanel("powerhorse"),
tabPanel("redbull")
)

al<-  
tabsetPanel(
tabPanel("salted"),
tabPanel("roasted")
)
pst<-  
tabsetPanel(
tabPanel("flavourd"),
tabPanel("roasted")
)

runApp(list(
ui = shinyUI( fluidPage(

sidebarLayout( 
  sidebarPanel(width = 2),      
  mainPanel(tabsetPanel(id='conditioned',
                        tabPanel("sweets",value=1,
                                 tabsetPanel(
                                   tabPanel("biscuits",
                                            tabsetPanel(bisc)),
                                   tabPanel("choc",
                                            tabsetPanel(choc)),
                                   tabPanel("gum",
                                            tabsetPanel(gm))
                                 )),
                        tabPanel("nuts",value=2,
                                 tabsetPanel(
                                   tabPanel("almonds",
                                            tabsetPanel(al)),
                                   tabPanel("pistcio",
                                            tabsetPanel(pst))
                                 )),

                        tabPanel("drinks",value=3,
                                 tabsetPanel(
                                   tabPanel("hotdrinks",
                                            tabsetPanel(hdrinks)),
                                   tabPanel("juices",
                                            tabsetPanel(jcs)),
                                   tabPanel("energydrinks",
                                            tabsetPanel(ngdrinks))

                                 ))
                        ))
  ))),

 server = function(input, output, session) {}
))

as you can see this approach is too vulnerable to mistake, thanks in advance.


回答1:


hotdrinks<-list("tea","green tea") 
juices<-list("orange","mango") 
energydrinks<-list("powerhorse","redbull") 
drinks<-list("hotdrinks"=hotdrinks, "juices"=juices, "energydrinks"=energydrinks) 

lst_drinks <- lapply(seq_along(drinks), 
                     #browser()
                     #create 2nd level, tab name with the corresponding 3rd level list  
                     function(x) tabPanel(names(drinks[x]),
                                          #create tabsetPanel for hdrinks, jcs, ngdrinks level i.e. 3rd level 
                                          do.call("tabsetPanel", 
                                                  lapply(drinks[[x]], function(y) tabPanel(y))
                                                  )
                                          )
                     )

hdrinks<-  
  tabsetPanel(
    tabPanel("tea"),
    tabPanel("green tea")
  )
jcs<-  
  tabsetPanel(
    tabPanel("orange"),
    tabPanel("mango")
  )
ngdrinks<-  
  tabsetPanel(
    tabPanel("powerhorse"),
    tabPanel("redbull")
  )

runApp(list(
  ui = shinyUI(fluidPage(
    sidebarLayout( 
      sidebarPanel(width = 2),      
      mainPanel(tabsetPanel(id='conditioned',
                            tabPanel("drinks",value=3,
                                     tabsetPanel(
                                       tabPanel("hotdrinks",
                                                #No need for tabsetPanel as hdrinks already has one, therefore I removed it in lapply
                                                tabsetPanel(hdrinks)),
                                       tabPanel("juices",
                                                tabsetPanel(jcs)),
                                       tabPanel("energydrinks",
                                                tabsetPanel(ngdrinks))

                                     )),
                            tabPanel("drinks-test",
                                     do.call("tabsetPanel", lst_drinks))
                                     ))
    ))),

  server = function(input, output, session) {}
))

The Full solution

hotdrinks<-list("tea","green tea") 
juices<-list("orange","mango") 
energydrinks<-list("powerhorse","redbull") 
drinks<-list("hotdrinks"=hotdrinks,"juices"=juices,"energydrinks"=energydrinks) 

biscuits<-list("loacker","tuc") 
choc<-list("aftereight","lindt") 
gum<-list("trident","clortes") 
sweets<-list("gum"=gum,"biscuits"=biscuits,"choc"=choc)

all <- list("drinks"=drinks, "sweets"=sweets)

all_lst <- lapply(seq_along(all), function(z) tabPanel(names(all)[z], 
                                                       do.call("tabsetPanel", 
                                                               lapply(seq_along(all[[z]]), function(x) tabPanel(names(all[[z]][x]), 
                                                                                                                do.call("tabsetPanel", 
                                                                                                                        lapply(all[[z]][[x]], function(y) tabPanel(y, DT::dataTableOutput(y)))
                                                                                                                        )
                                                                                                                )
                                                                      )
                                                               )
                                                       )
                  )

runApp(list(
  ui = shinyUI(fluidPage( 
    sidebarLayout( 
      sidebarPanel(width = 2),      
      mainPanel(do.call("tabsetPanel", c(id='conditioned', all_lst)))
      ))),
  server = function(input, output, session) {
    observe({
      nms = unlist(all)
      names(nms) <- sub('\\d', '', names(nms))
      for(i in seq_along(nms)){
        #browser()
        local({
          nm      = nms[i]
          CAT_var = unlist(strsplit(names(nm), '\\.'))[1]
          PN_var  = unlist(strsplit(names(nm), '\\.'))[2]
          SP_var  = nm[[1]]
          output[[SP_var]] <- DT::renderDataTable({filter(t1, CAT==CAT_var, PN==PN_var, SP==SP_var)})
        })
      }
    })
  }
))


来源:https://stackoverflow.com/questions/59079852/in-r-shiny-how-to-automatically-or-based-on-function-tabpanel-given-we-have-3

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!