首先,你必须使用preDrawCallback和drawCallback这两个选项,否则Shiny不知道选择器:
output[["foo"]] <- renderDT(
data, escape = FALSE, selection = 'none', server = FALSE,
options = list(
dom = 't',
paging = FALSE,
ordering = FALSE,
preDrawCallback = JS(
"function() { Shiny.unbindAll(this.api().table().node()); }"
),
drawCallback = JS(
"function() { Shiny.bindAll(this.api().table().node()); }"
)
)
)
现在,您可以使用两个反应值来存储行和物种:
row <- reactiveVal()
species <- reactiveVal()
然后,为每一行定义一个观察者:
lapply(1:nrow(data), function(i){
selector <- paste0("change", i)
observeEvent(input[[selector]], {
row(i)
species(input[[selector]])
})
})
完整应用:
library(shiny)
library(DT)
ui <- fluidPage(
br(),
DTOutput('foo'),
br(),
wellPanel(
textOutput("text")
)
)
server <- function(input, output, session) {
data <- head(iris, 5)
data$species_selector <- vapply(1:nrow(data), function(i){
as.character(selectInput(
paste0("change", i),
label = paste0("change", i),
choices = unique(iris$Species),
width = "100px"
))
}, character(1))
output[["foo"]] <- renderDT(
data, escape = FALSE, selection = 'none', server = FALSE,
options = list(
dom = 't',
paging = FALSE,
ordering = FALSE,
preDrawCallback = JS(
"function() { Shiny.unbindAll(this.api().table().node()); }"
),
drawCallback = JS(
"function() { Shiny.bindAll(this.api().table().node()); }"
)
)
)
row <- reactiveVal()
species <- reactiveVal()
lapply(1:nrow(data), function(i){
selector <- paste0("change", i)
observeEvent(input[[selector]], {
row(i)
species(input[[selector]])
})
})
output[["text"]] <- renderText({
sprintf("Row %d --- Species %s", row(), species())
})
}
shinyApp(ui, server)