在 Shiny 中,如何在没有 javascript 的情况下一次显示一个选项卡,等等
In Shiny, how to make tabs appear one at a time without javascript, etc
我想使用一组 if
和 else
语句来 select 哪个 tabsetPanel
使用。这个想法是在用户执行先决条件任务时出现新的选项卡。我创建的内容似乎试图做到这一点,但现有选项卡会重新加载,重置选项卡的状态,因此删除刚刚添加的选项卡。在我的示例中,您可以看到第二个选项卡闪现,然后消失。如何使每个选项卡中的输入在重新创建 tabsetPanel
时保持不变?我阅读了对 a similar question 的回复,但我不熟悉 javascript(或该答案中 tags$script
中的任何代码),所以我想要一个只需要 R 代码的解决方案.
该应用是 available on shinyapps。
代码贴在下面,也是available on github.
ui.R
library(shiny)
shinyUI(pageWithSidebar(
headerPanel("Subset data before analyzing"),
sidebarPanel(),
mainPanel(uiOutput("Panels"))
))
server.R
library(shiny)
shinyServer(function(input, output) {
#This is the data
d1 = data.frame(
Student = c("Abe","Bill","Clare","Abe","Bill","Clare"),
Class = c("ELA","ELA","ELA","Math","Math","Math"),
Grade = c(71,72,73,74,75,76))
# This pulls a list of unique names from the Student column of the data and creates a checklist
output$StudentCheckList <- renderUI({
if(is.null(d1)){return ()
} else tagList(
checkboxGroupInput(inputId = "SelectedStudents",
label = "Which students you like to select?",
choices = unique(as.character(d1$Student)))
)
})
#This pulls a list of unique names from the Class column of the data and creates a checklist
output$ClassCheckList <- renderUI({
if(is.null(d1)){return ()
} else tagList(
checkboxGroupInput(inputId = "SelectedClasses",
label = "Which classes would you like to select?",
choices = unique(as.character(d1$Class)))
)
})
# This generates the table of data subsetted by the checklist selections
output$Summary = renderTable({
if(is.null(d1)){return ()
} else {
d3 = d1[which(as.character(d1$Student) %in% input$SelectedStudents),]
d3 = d3[which(as.character(d3$Class) %in% input$SelectedClasses),]
return(d3)
}
})
# These are the definitions for the individual panels
p1 = reactive(tabPanel("Pick Students",uiOutput("StudentCheckList")))
p2 = reactive(tabPanel("Pick Classes",uiOutput("ClassCheckList")))
p3 = reactive(tabPanel("Summary",tableOutput("Summary")))
# This generates the actual panel layout
output$Panels = renderUI({
tagList(
if(is.null(d1)){return()
} else if (length(input$SelectedStudents)==0){tabsetPanel(p1())
} else if (length(input$SelectedClasses)==0){tabsetPanel(p1(),p2())
} else tabsetPanel(p1(),p2(),p3())
)
})
})
我找到了解决这个问题的办法。它涉及几个组件。
首先,我必须创建一个新版本的 tabsetPanel
函数(我称之为 tabsetPanel2
。它与 tabsetPanel
本质上相同,只是它删除了任何 tabPanel
为 NULL 的对象。这样,任何不应出现的 tabPanel
对象都可以设置为 NULL,并且对 tabsetPanel
的调用不必更改。
其次,我必须创建反应对象来保存用户在驻留在 tabPanel
上的每个小部件上所做的选择,并将小部件的 selected
参数设置为该反应目的。这样,当 tabsetPanel2
重建时,它会加载之前输入的信息。
第三,我必须创建一个反应对象来保存所选选项卡的名称。这样,当 tabsetPanel2
重建时,它会自动转到用户刚刚所在的选项卡。
所有代码都可以在问题中提到的 github 存储库中找到。
我想使用一组 if
和 else
语句来 select 哪个 tabsetPanel
使用。这个想法是在用户执行先决条件任务时出现新的选项卡。我创建的内容似乎试图做到这一点,但现有选项卡会重新加载,重置选项卡的状态,因此删除刚刚添加的选项卡。在我的示例中,您可以看到第二个选项卡闪现,然后消失。如何使每个选项卡中的输入在重新创建 tabsetPanel
时保持不变?我阅读了对 a similar question 的回复,但我不熟悉 javascript(或该答案中 tags$script
中的任何代码),所以我想要一个只需要 R 代码的解决方案.
该应用是 available on shinyapps。
代码贴在下面,也是available on github.
ui.R
library(shiny)
shinyUI(pageWithSidebar(
headerPanel("Subset data before analyzing"),
sidebarPanel(),
mainPanel(uiOutput("Panels"))
))
server.R
library(shiny)
shinyServer(function(input, output) {
#This is the data
d1 = data.frame(
Student = c("Abe","Bill","Clare","Abe","Bill","Clare"),
Class = c("ELA","ELA","ELA","Math","Math","Math"),
Grade = c(71,72,73,74,75,76))
# This pulls a list of unique names from the Student column of the data and creates a checklist
output$StudentCheckList <- renderUI({
if(is.null(d1)){return ()
} else tagList(
checkboxGroupInput(inputId = "SelectedStudents",
label = "Which students you like to select?",
choices = unique(as.character(d1$Student)))
)
})
#This pulls a list of unique names from the Class column of the data and creates a checklist
output$ClassCheckList <- renderUI({
if(is.null(d1)){return ()
} else tagList(
checkboxGroupInput(inputId = "SelectedClasses",
label = "Which classes would you like to select?",
choices = unique(as.character(d1$Class)))
)
})
# This generates the table of data subsetted by the checklist selections
output$Summary = renderTable({
if(is.null(d1)){return ()
} else {
d3 = d1[which(as.character(d1$Student) %in% input$SelectedStudents),]
d3 = d3[which(as.character(d3$Class) %in% input$SelectedClasses),]
return(d3)
}
})
# These are the definitions for the individual panels
p1 = reactive(tabPanel("Pick Students",uiOutput("StudentCheckList")))
p2 = reactive(tabPanel("Pick Classes",uiOutput("ClassCheckList")))
p3 = reactive(tabPanel("Summary",tableOutput("Summary")))
# This generates the actual panel layout
output$Panels = renderUI({
tagList(
if(is.null(d1)){return()
} else if (length(input$SelectedStudents)==0){tabsetPanel(p1())
} else if (length(input$SelectedClasses)==0){tabsetPanel(p1(),p2())
} else tabsetPanel(p1(),p2(),p3())
)
})
})
我找到了解决这个问题的办法。它涉及几个组件。
首先,我必须创建一个新版本的 tabsetPanel
函数(我称之为 tabsetPanel2
。它与 tabsetPanel
本质上相同,只是它删除了任何 tabPanel
为 NULL 的对象。这样,任何不应出现的 tabPanel
对象都可以设置为 NULL,并且对 tabsetPanel
的调用不必更改。
其次,我必须创建反应对象来保存用户在驻留在 tabPanel
上的每个小部件上所做的选择,并将小部件的 selected
参数设置为该反应目的。这样,当 tabsetPanel2
重建时,它会加载之前输入的信息。
第三,我必须创建一个反应对象来保存所选选项卡的名称。这样,当 tabsetPanel2
重建时,它会自动转到用户刚刚所在的选项卡。
所有代码都可以在问题中提到的 github 存储库中找到。