首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用R/Shiny创建动态数量的输入元素

使用R/Shiny创建动态数量的输入元素
EN

Stack Overflow用户
提问于 2013-10-02 13:23:09
回答 3查看 29.8K关注 0票数 62

我正在写一个闪亮的应用程序,用于可视化我公司的保险福利计划。以下是我希望发生的事情:

  • 我将有一个selectInputsliderInput,用户将在其中选择其医疗计划中的个人数量
  • 将出现匹配数量的双面滑块(每个成员一个)
  • 然后他们可以在其计划中输入每个成员的最佳/最坏情况医疗费用估计

< code >H19我有代码将采用这些估计值并并排创建绘图,说明三个计划产品的预测成本,以便他们可以根据自己的估计决定哪个最便宜

下面是我当前使用硬编码输入的ui.R文件,模拟一个四口之家:

代码语言:javascript
运行
复制
shinyUI(pageWithSidebar(

  headerPanel("Side by side comparison"),

  sidebarPanel(

    selectInput(inputId = "class", label = "Choose plan type:",
                list("Employee only" = "emp", "Employee and spouse" = "emp_spouse",
                     "Employee and child" = "emp_child", "Employee and family" = "emp_fam")),

    sliderInput(inputId = "ind1", label = "Individual 1",
                min = 0, max = 20000, value = c(0, 2500), step = 250),

    sliderInput(inputId = "ind2", label = "Individual 2",
                min = 0, max = 20000, value = c(0, 2500), step = 250),

    sliderInput(inputId = "ind3", label = "Individual 3",
                min = 0, max = 20000, value = c(0, 2500), step = 250),

    sliderInput(inputId = "ind4", label = "Individual 4",
                min = 0, max = 20000, value = c(0, 2500), step = 250)
    ),

  mainPanel(
    tabsetPanel(  
    tabPanel("Side by Side", plotOutput(outputId = "main_plot", width = "100%")),
    tabPanel("Summary", tableOutput(outputId = "summary"))
  )
)))

它看起来是这样的(透明的末端部分是来自两个计划的HSA贡献的结果。我认为这是一种很好的方式来显示保费和医疗费用,同时显示公司HSA贡献的影响。因此,您只需比较纯色的长度)。

我见过这样的示例like this,其中UI输入本身是固定的(在本例中,存在一个checkboxGroupInput,但是它的内容是根据从另一个UI输入中选择的内容进行裁剪的),但是我还没有见过裁剪作为另一个UI输入内容的结果而产生的输入元素的数量(或者类型)的示例。

对此有什么建议(这是可能的吗)?

我最后的办法是创建15个输入滑块,并将它们初始化为零。我的代码可以很好地工作,但我希望通过不创建那么多滑块来清理界面,只为偶尔有一个非常大的家庭的用户创建。

基于Kevin Ushay的answer的更新

我尝试了server.R路线,并获得了以下内容:

代码语言:javascript
运行
复制
shinyServer(function(input, output) {

  output$sliders <- renderUI({
    members <- as.integer(input$members) # default 2
    max_pred <- as.integer(input$max_pred) # default 5000
    lapply(1:members, function(i) {
      sliderInput(inputId = paste0("ind", i), label = paste("Individual", i),
                  min = 0, max = max_pred, value = c(0, 500), step = 100)
    })

  })

})

紧接着,我尝试从input中提取每个人的开销的值:

代码语言:javascript
运行
复制
expenses <- reactive({
    members <- as.numeric(input$members)

    mins <- sapply(1:members, function(i) {
      as.numeric(input[[paste0("ind", i)]])[1]
    })

    maxs <- sapply(1:members, function(i) {
      as.numeric(input[[paste0("ind", i)]])[2]
    })

    expenses <- as.data.frame(cbind(mins, maxs))
})

最后,我有两个函数,这两个函数创建对象来存储数据框,以便根据最低和最高的医疗费用估计进行绘图。它们名为best_caseworst_case,都需要expenses对象才能工作,所以我把它称为我从this question学到的第一行

代码语言:javascript
运行
复制
best_case <- reactive({

    expenses <- expenses()

    ...

)}

我得到了一些错误,所以我使用browser()遍历了expenses位,并注意到像input$ind1这样的特殊东西似乎并不存在于expenses函数中。

我还尝试了其中的各种print()语句,看看发生了什么。最令人惊讶的是,当我将print(names(input))作为函数的第一行时:

代码语言:javascript
运行
复制
[1] "class"    "max_pred" "members" 

[1] "class"    "ind1"     "ind2"     "max_pred" "members" 

我得到了两个输出,我相信这是由于定义了expenses并随后调用了它。奇怪的是。当worst_case使用完全相同的expenses <- expense()行时,我不会得到第三行代码。

如果我在expenses函数中执行类似print(expenses)的操作,我也会得到重复的结果:

代码语言:javascript
运行
复制
# the first
  mins maxs
1   NA   NA
2   NA   NA

# the second
  mins maxs
1    0  500
2    0  500

关于为什么我的ind1ind2input元素直到第二次调用expenses才会出现,从而阻止正确创建数据框,有什么建议吗?

EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19130455

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档