R Shiny:处理数据表中的动作按钮

Pat*_*her 14 r shiny

我有一个带有数据表的R Shiny应用程序.一列包含具有唯一ID的操作按钮.我想处理这些按钮的点击,但不幸的是,我的事件处理代码(一个简单的打印语句)永远不会被执行.看到这个自包含的例子(app.R):

library(shiny)
library(DT)

ui <- shinyUI(
    fluidPage(
        title = "DataTable with Buttons",
        fluidRow(
            column(
                width = 8,
                dataTableOutput("employees")
            )
        )
    )
)

server <- shinyServer(function(input, output) {
    df <- data.frame(
        name = c('Dilbert', 'Alice', 'Wally', 'Ashok', 'Dogbert'),
        motivation = c(62, 73, 3, 99, 52),
        stringsAsFactors = FALSE
    )
    fireButtons <- list()
    fireButtonIds <- list()
    for (r in rownames(df)) {
        id <- paste("fire_", r, sep = "")
        fireButtonIds[[r]] <- id
        button <- actionButton(id, label = "Fire")
        fireButtons[[r]] <- as.character(button)
    }
    df$actions <- fireButtons
    dt <- datatable(df, colnames = c("#", "Name", "Motivation", "Actions"))
    output$employees <- renderDataTable(dt)


    for (id in fireButtonIds) {
        # binding doesn't work
        # - is the path wrong?
        # - is it because the button is really a string, not an object?
        observeEvent(input$employees$x$data$actions[[id]], {
            print(paste("click on", i))
        })
    }
})

shinyApp(ui = ui, server = server)
Run Code Online (Sandbox Code Playgroud)

我看到两个可能的问题:

  1. 我正在使用的路径(input$employees$x$data$actions[[id]])是错误的
  2. 我正在使用的路径是正确的,它并没有指向可以实际处理的东西,即它只是一个HTML字符串而不是一个按钮对象.

或者也许有更好的方法将按钮放在数据表中......?

kos*_*str 26

这会完成你想要做的吗?

library(shiny)
library(DT)

shinyApp(
  ui <- fluidPage(
    DT::dataTableOutput("data"),
    textOutput('myText')
  ),

  server <- function(input, output) {

    myValue <- reactiveValues(employee = '')

    shinyInput <- function(FUN, len, id, ...) {
      inputs <- character(len)
      for (i in seq_len(len)) {
        inputs[i] <- as.character(FUN(paste0(id, i), ...))
      }
      inputs
    }

    df <- reactiveValues(data = data.frame(

      Name = c('Dilbert', 'Alice', 'Wally', 'Ashok', 'Dogbert'),
      Motivation = c(62, 73, 3, 99, 52),
      Actions = shinyInput(actionButton, 5, 'button_', label = "Fire", onclick = 'Shiny.onInputChange(\"select_button\",  this.id)' ),
      stringsAsFactors = FALSE,
      row.names = 1:5
    ))


    output$data <- DT::renderDataTable(
      df$data, server = FALSE, escape = FALSE, selection = 'none'
    )

    observeEvent(input$select_button, {
      selectedRow <- as.numeric(strsplit(input$select_button, "_")[[1]][2])
      myValue$employee <<- paste('click on ',df$data[selectedRow,1])
    })


    output$myText <- renderText({

      myValue$employee

    })

  }
)
Run Code Online (Sandbox Code Playgroud)

  • 很抱歉没有解释.您在服务器代码中看到的第一个函数是创建和命名输入的函数.然后,我们应用该函数在响应数据帧中创建列.该数据帧被放置在DT输出中,它出现在UI中.事件处理函数(observeEvent)会随时响应任何select_button(我们创建的5个).在这种情况下,它会更改无效值(myValue $ employee)以匹配员工的行ID名称.然后将该值传递给myText输出并在UI中呈现.希望有道理! (3认同)
  • 老问题,但对于不开火的问题,您有 2 个选择。使用 `shiny` 版本 &gt;= 1.1 你可以使用 `Shiny.setInputValue(\"select_button\", this.id, {priority: \"event\"})`(`setInputValue` 与 `onInputChange` 基本相同) . 在 `shiny` 版本 &lt;1.1 的情况下,您可以使用 `Shiny.onInputChange(\"select_button\", [this.id, Math.random()]) `。问题是`shiny` 只对变化作出反应,因此你必须以`shiny` 知道它是一个新值的方式设置值。在较新的版本中,您可以明确地做到这一点,在较旧的版本中,您必须使用带有随机变量的技巧。 (3认同)
  • 如果您在同一个按钮上单击两次,这实际上不会触发。有什么解决办法吗? (2认同)