我正在尝试创建一个Shiny应用程序,该应用程序的表单可以根据存储在数据帧中的输入生成选项卡和输入(例如,textInput、selectInput等)。我在下面创建了一个简单的例子,解释了我正在努力实现的目标。有什么想法吗?我想使用tidyverse,但另一种方法会起作用。
# This is what I want
tabsetPanel(
tabPanel("1",
textInput("a", "a_lab"),
textInput("b", "b_lab")),
tabPanel("2",
textInput("c", "c_lab"),
textInput("d", "d_lab")),
tabPanel("3",
textInput("e", "e_lab"),
textInput("f", "f_lab"))
)
# I have a dataframe that looks like this as my input
tab_str <- data.frame(
tabnam=c(1,1,2,2,3,3),
id=letters[1:6],
lab=paste0(letters[1:6],"_lab")
)
# My function to make input controls are something like this
make_ctrl <- function(id, lab) textInput(id, lab)
# How can I obtain what I want--example at the top--using a "loop" approach;
# if possible using tidyverse; obviously what I have below is not working
tab_str %>% map(make_ctrl, id=tab_str$id)
我对tidyverse包不太熟悉,所以这里有一个基本的R示例,让我了解tidyverses等价物。
基本要点是:
- 将输入数据映射到输入控件
- 将相关控件分组到列表中
- 对于每个组,从子控件列表中构造一个
tabPanel
- 从
tabPanel
的列表中构造tabsetPanel
此示例使用:
apply
映射到data.frame
行tapply
对列表元素进行分组lapply
映射到列表do.call
使用列表将参数传递到函数中
inputs_by_tab <- tab_str %>%
apply(1, function(row) textInput(row["id"], row["lab"])) %>%
tapply(tab_str$tabnam, list)
tabs <- lapply(names(inputs_by_tab), function(name) {
do.call(tabPanel, list(title = name, inputs_by_tab[[name]]))
})
tabset <- do.call(tabsetPanel, tabs)