我想收集个人信息(姓名和年龄)作为用户输入随附的演示代码.初始个体数为1,当用户增加/减少个体数时,它会react 性地增加/减少相应的行以收集个体信息.我的问题是,在增加/减少个体数量时,如何避免删除当前的输入信息.例如,screenshot 1显示用户(me)输入的个人1的信息.当我将个体数的值更改为2时,我之前输入的信息被删除(screenshot 2),我必须重新输入个体1的信息.当我将个体数增加到2时,我预计会是screenshot 3(个体1的信息不会被删除).有人能帮我吗?谢谢

Update on 05/15/2022

由于我在过go 一周没有收到任何关于这个问题的新 comments /答案,我接受了jpdugo17的答案.对于那些有类似问题的人,请注意,公认答案中的numericInputactionButton没有react (您可以将其删除或更改为textInput).再次感谢@jpdugo17的帮助.

Example code

library(shiny)
ui <- fluidPage(
  tabsetPanel(
    tabPanel(
      h4("Individual Information"),
      fluidRow(column(4,numericInput("ninds",
                                     label = "Number of individuals",
                                     value = 1, min = 1, step = 0.5, width = "300px"))),
      br(),
      fluidRow(column(2,align = "center",strong("Individual #")),
               column(5,align = "center",strong("Individual Name")),
               column(5,align = "center",strong("Age"))),
      fluidRow(
        column(2,wellPanel(uiOutput("indNum"))),
        column(5,wellPanel(uiOutput("Name"))),
        column(5,wellPanel(uiOutput("Age"))))
    )
  )
)

server <- function(input, output) {
  # create reactive variable paste0("individualNum", i) for further using
  output$indNum <- renderUI({
    num <- as.integer(input$ninds)
    req(num)
    lapply(1:num, function(i) {
      numericInput(paste0("individualNum", i), value = i, label = "", max = i, min = i)
    })
  })
  # create reactive variable paste0("name", i) for further using 
  output$Name <- renderUI({
    num <- as.integer(input$ninds)
    req(num)
    lapply(1:num, function(i) {
      textInput(paste0("name", i), label = "")
    })
  })
  # create reactie variable paste0("age", i) for further using 
  output$Age <- renderUI({
    num <- as.integer(input$ninds)
    req(num)
    lapply(1:num, function(i) {
      numericInput(paste0("age", i), label = "", value = 0)
    })
  })
}

# Run the app ----
shinyApp(ui, server)

screenshot-1 screenshot-1 screenshot-2 screenshot-2 screenshot-3 screenshot-3

推荐答案

Edit:

我们可以将isolate与输入的当前值一起使用,并将其作为numericInputtextInput中的值参数传递.这是可行的,因为任何尚不存在的输入都会产生NULL.

server <- function(input, output) {
  # create reactive variable paste0("individualNum", i) for further using

  num <- reactive({
    req(input$ninds)
    input$ninds
  })

  output$indNum <- renderUI({
    lapply(1:num(), function(i) {
      numericInput(paste0("individualNum", i), value = i, label = "", max = i, min = i)
    })
  })
  # create reactive variable paste0("name", i) for further using
  output$Name <- renderUI({
    lapply(1:num(), function(i) {
      textInput(paste0("name", i), label = "", value = isolate(input[[paste0("name", i)]]))
    })
  })
  # create reactie variable paste0("age", i) for further using
  output$Age <- renderUI({
    lapply(1:num(), function(i) {
      numericInput(paste0("age", i), label = "", value = isolate(input[[paste0("age", i)]]))
    })
  })
}

原始答案使用insertUI:

我们可以实现这样的逻辑:创建一个计数器来存储当前的输入编号,制作两个按钮,一个用于添加,另一个用于删除输入.我们必须用一个具有唯一id的div来包装每个输入(因为输入函数通常会添加多个元素).

library(shiny)
library(purrr)

ui <- fluidPage(
  tabsetPanel(
    tabPanel(
      h4("Individual Information"),
      fluidRow(
        column(
          4, fluidRow(
            column(6, numericInput("ninds",
              label = "Number of individuals",
              value = 1, min = 1, step = 0.5, width = "300px"
            )), column(3, actionButton("add_ui", "Add Individual", style = "background-color: green;")),
            column(3, actionButton("remove_ui", "Remove Individual", style = "background-color: red;"))
          )
        )
      ),
      br(),
      fluidRow(
        column(2, align = "center", strong("Individual #")),
        column(5, align = "center", strong("Individual Name")),
        column(5, align = "center", strong("Age"))
      ),
      fluidRow(
        column(2, wellPanel(id = "IndNumber")),
        column(5, wellPanel(id = "Name")),
        column(5, wellPanel(id = "Age"))
      )
    )
  )
)


server <- function(input, output) {

  # track the number of inputs
  ui_counter <- reactiveVal(1)

  observeEvent(input$add_ui, {
    div_nms <- map_chr(c("individualNum", "name", "age"), ~ paste0("div", .x, ui_counter()))

    # individual number
    insertUI(
      selector = "#IndNumber",
      ui = div(
        id = div_nms[[1]],
        numericInput(paste0("individualNum", ui_counter()),
          label = "",
          value = ui_counter(),
          min   = ui_counter(),
          max   = ui_counter()
        )
      )
    )

    # name input
    insertUI(
      selector = "#Name",
      ui = div(id = div_nms[[2]], textInput(paste0("name", ui_counter()),
        label = ""
      ))
    )

    # age input
    insertUI(
      selector = "#Age",
      ui = div(id = div_nms[[3]], numericInput(paste0("age", ui_counter()),
        label = "",
        value = 0
      ))
    )


    ui_counter(ui_counter() + 1)
  })

  # observer to remove the divs containing the inputs
  observeEvent(input$remove_ui, {
    if (ui_counter() > 1) {
      walk(c("individualNum", "name", "age"), ~ removeUI(paste0("#div", .x, ui_counter() - 1)))
      ui_counter(ui_counter() - 1)
    }
  })
}

# Run the app ----
shinyApp(ui, server)

R相关问答推荐

使用map()内的公式()创建多个公式

如果行和列名以相同的开头,将矩阵值设置为0

寻找图片边缘

为什么st_join(ob1,ob2,left = True)返回具有比ob1更多功能的sf对象?

r替换lme S4对象的字符串的一部分

使用整齐的计算(curl -curl )和杂音

在ggplot中为不同几何体使用不同的 colored颜色 比例

为了网络分析目的,将数据框转换为长格式列联表

仅在R中的数据集开始和结束时删除所有 Select 列的具有NA的行

'使用`purrr::pwalk`从嵌套的嵌套框架中的列表列保存ggplots时出现未使用的参数错误

按组内中位数分类

删除字符串R中的重复项

减少雨云面之间的间距并绘制所有统计数据点

R中治疗序列的相对时间指数

如何在GALT包的函数&geom_x样条线中调整线宽

整理ggmosaic图的标签

R-使用stri_trans_General()将其音译为德语字母

如果满足条件,则替换列的前一个值和后续值

在不重复主题的情况下重新排列组

roxygen2正在处理太多的文件