【问题标题】:How to add a button that removes input rows?如何添加删除输入行的按钮?
【发布时间】:2019-08-20 10:02:44
【问题描述】:

我有一些代码来编写一个小型闪亮应用程序,我需要为其添加输入行,如果需要,再次删除它们。我已经知道如何添加输入,但我不知道如何删除它们。

这是我的代码的 MWE。没有输出,因为我无法共享生成输出的代码后面的 excel 表。但是,只需帮助我找到正确的代码以删除具有完整输入的添加行(第一行除外)就足够了:

library(shiny)

GeographyList <- c("Africa","Asia Pacific","Europe","Global", "United States","Latin America & Caribbean")
RegionList <- c("Emerging", 
                "Developed")
ClassList <- c("1",
               "2",
               "3")


# Define UI for app that draws a plot ----
ui <- fluidPage(
  fluidRow(
    mainPanel(
      uiOutput("inputwidgets"),

      actionButton("number", 
                   "Add Row"),

      # Input: Click to update the Output
      actionButton("update", "Update View"),

      # Output: Plot ----
      h4("Allocation"),
      plotOutput("distPlot")
      )
    )
  )


# Define server logic required to call the functions required ----
server <- function(input, output, session) {

  # Get new input by clicking Add Row
  observeEvent(input$number, {
    output$inputwidgets = renderUI({
      input_list <- lapply(1:input$number, function(i) {
        # for each dynamically generated input, give a different name
        fluidRow(
          column(2,
                 selectInput(paste0("Geography", i),
                             label = paste0("Geography", i),
                             choices = GeographyList,
                             multiple = FALSE,
                             selected = NA)
          ),
          column(3,
                 selectInput(paste0("Region", i),
                             label = paste0("Region", i),
                             choices = RegionList,
                             multiple = FALSE,
                             selected = NA)
          ),
          column(4,
                 selectInput(paste0("Class", i),
                             label = paste0("Class", i),
                             choices = ClassList,
                             multiple = FALSE,
                             selected = NA)
          ),
          column(3, 

                 # Input: Specify the amount ----
                 numericInput(paste0("amount",i), label="Amount", 0)
          ))
      })
      do.call(tagList, input_list)
    })

  })


  output$distPlot <- renderPlot({
    if (input$update == 0)
      return()

    isolate(input$number)
    isolate(input$amount)
    slices <- c(input$amount1,input$amount2,input$amount3,input$amount4)
    pie(slices)
  })


}

# Create Shiny app ----
shinyApp(ui = ui, server = server)

感谢任何提示,因为我是闪亮的新手!提前致谢。

【问题讨论】:

标签: r shiny


【解决方案1】:

您可以根据添加按钮和删除按钮触发的 reactiveValue 构建您的 lapply 循环:

1.编辑:根据lapply 行在output$distPlot 中使用sapply

2。编辑:使用现有输入值

library(shiny)

GeographyList <- c("Africa","Asia Pacific","Europe","Global", "United States","Latin America & Caribbean")
RegionList <- c("Emerging",
                "Developed")
ClassList <- c("1",
               "2",
               "3")

# Define UI for app that draws a plot ----
ui <- fluidPage(
    fluidRow(
        mainPanel(
            uiOutput("inputwidgets"),

            actionButton("number",
                         "Add Row"),
            actionButton("delete_number",
                         "Delete Row"),


            # Input: Click to update the Output
            actionButton("update", "Update View"),

            # Output: Plot ----
            h4("Allocation"),
            plotOutput("distPlot")
        )
    )
)


# Define server logic required to call the functions required ----
server <- function(input, output, session) {

    reac <- reactiveValues()

    observeEvent(c(input$number,input$delete_number), {
        # you need to add 1 to not start with 0
        add <- input$number+1
        # restriction for delete_number > number
        delete <- if(input$delete_number > input$number) add else input$delete_number
        calc <- add - delete
        reac$calc <- if(calc > 0) 1:calc else 1
    })
    # Get new input by clicking Add Row
    observe({
        req(reac$calc)
        output$inputwidgets = renderUI({
            input_list <- lapply(reac$calc, function(i) {
                Geography <- input[[paste0("Geography",i)]]
                Region <- input[[paste0("Region",i)]]
                Class <- input[[paste0("Class",i)]]
                amount <- input[[paste0("amount",i)]]

                # for each dynamically generated input, give a different name
                fluidRow(
                    column(2,
                           selectInput(paste0("Geography", i),
                                       label = paste0("Geography", i),
                                       choices = GeographyList,
                                       multiple = FALSE,
                                       selected = if(!is.null(Geography)) Geography
                           )
                    ),
                    column(3,
                           selectInput(paste0("Region", i),
                                       label = paste0("Region", i),
                                       choices = RegionList,
                                       multiple = FALSE,
                                       selected = if(!is.null(Region)) Region
                           )
                    ),
                    column(4,
                           selectInput(paste0("Class", i),
                                       label = paste0("Class", i),
                                       choices = ClassList,
                                       multiple = FALSE,
                                       selected = if(!is.null(Class)) Class
                           )
                    ),
                    column(3,

                           # Input: Specify the amount ----
                           numericInput(
                               paste0("amount",i),
                               label="Amount",
                               value = if(!is.null(amount)) amount else 0
                           )
                    ))
            })
            do.call(tagList, input_list)
        })

    })


    output$distPlot <- renderPlot({
        req(reac$calc, input$update)

        slices <- sapply(reac$calc, function(i) {
            c(input[[paste0("amount",i)]])
        })

        pie(slices)
    })

}

# Create Shiny app ----
shinyApp(ui = ui, server = server)

【讨论】:

  • 谢谢,这似乎可行,但是,当我删除一行时,输入似乎仍在后台运行!我有一个绘图作为输出,在删除行时不会更新 - 你知道如何解决这个问题吗?
  • 您的情节现在是否还取决于reac$calc 或您为反应值指定的任何名称?
  • 这是我的情节的代码:` output$distPlot
  • 我也不确定如何获得比使用 amount1 amount2 等更好的解决方案来显示绘图,以防有四个以上的输入!你对此有什么想法吗?
  • 抱歉,您还没有意识到您也发布了您的情节 sn-p。您可以像使用 lapply 一样使用 sapply,在这里获取 slice 的向量。我会更新我的代码
猜你喜欢
  • 1970-01-01
  • 2017-09-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-05
相关资源
最近更新 更多