创建指示最后修改哪个小部件的闪亮反应变量
Creating Shiny reactive variable that indicates which widget was last modified
假设我们有一组小部件,每个小部件都有自己的输入标签。我们如何创建一个反应对象,其值是代表最后一个被修改的小部件的输入 ID 的字符?
例如,如果我们有
ui.R
shinyUI(fluidPage(
textInput('txt_a', 'Input Text A'),
textInput('txt_b', 'Input Text B")
))
server.R
shinyServer(function(input, output) {
last_updated_widget <- reactive({
#hypothetical code that indicates ID value of last updated widget
})
})
想要的结果如下。如果用户修改了第一个文本框,那么 last_updated_widget()
的值将是 "txt_a"
。如果他们修改第二个框,last_updated_widget()
的值将变为 "txt_b"
。我正在寻找一个结果,该结果延伸到将值设置为最后调整的任何小部件的 ID 的明显概括。
我希望它适用于任意数量的小部件输入,包括它们由 renderUI()
语句生成的情况。因此,不能为每个小部件制作单独的 reactive()
语句。但是,如果反应语句需要遍历所有小部件名称(或类似名称),我当然可以使用它。并且多个反应语句是可以的,只要它是一个固定的数量,而不是小部件数量的函数。
这似乎是一个非常简单的问题,所以当它成为我的障碍时,我感到很惊讶。我觉得解决方案真的很明显,我只是没有看到,所以如果是的话,我很抱歉把它变成一个新问题。但如有任何帮助,我们将不胜感激。
您可以使用 reactiveValues()
创建的反应值来存储上次使用的小部件的名称。稍后使用观察者跟踪每个小部件的 activity 并使用上次使用的小部件的名称更新反应值。
在下面的示例中,最后使用的小部件的名称存储在 last_updated_widget$v
中,并且每次更改时都会激活 verbatimTextOutput
。您可以在服务器的任何地方使用 last_updated_widget$v
。
library(shiny)
runApp(list(
ui = shinyUI(
fluidPage(
textInput('txt_a', 'Input Text A'),
textInput('txt_b', 'Input Text B'),
verbatimTextOutput("showLast")
)
),
server = function(input, output, session) {
last_updated_widget <- reactiveValues( v = NULL)
observe ({
input$txt_a
last_updated_widget$v <- "txt_a"
})
observe ({
input$txt_b
last_updated_widget$v <- "txt_b"
})
output$showLast <- renderPrint({
last_updated_widget$v
})
}
))
这是一个可行的解决方案,但由于嵌套 observe()
,它看起来有点笨拙。我不确定有什么更好的方法,但可能会有更好的方法。
基本上,使用 observe()
遍历所有可用输入,对于每个输入,使用另一个 observe()
,它只会在该输入更改时触发,并将变量设置为 id输入的。
runApp(shinyApp(
ui = shinyUI(
fluidPage(
textInput('txt_a', 'Input Text A'),
textInput('txt_b', 'Input Text B'),
uiOutput('txt_c_out'),
verbatimTextOutput("show_last")
)
),
server = function(input, output, session) {
output$txt_c_out <- renderUI({
textInput('txt_c', 'Input Text C')
})
values <- reactiveValues(
lastUpdated = NULL
)
observe({
lapply(names(input), function(x) {
observe({
input[[x]]
values$lastUpdated <- x
})
})
})
output$show_last <- renderPrint({
values$lastUpdated
})
}
))
假设我们有一组小部件,每个小部件都有自己的输入标签。我们如何创建一个反应对象,其值是代表最后一个被修改的小部件的输入 ID 的字符?
例如,如果我们有
ui.R
shinyUI(fluidPage(
textInput('txt_a', 'Input Text A'),
textInput('txt_b', 'Input Text B")
))
server.R
shinyServer(function(input, output) {
last_updated_widget <- reactive({
#hypothetical code that indicates ID value of last updated widget
})
})
想要的结果如下。如果用户修改了第一个文本框,那么 last_updated_widget()
的值将是 "txt_a"
。如果他们修改第二个框,last_updated_widget()
的值将变为 "txt_b"
。我正在寻找一个结果,该结果延伸到将值设置为最后调整的任何小部件的 ID 的明显概括。
我希望它适用于任意数量的小部件输入,包括它们由 renderUI()
语句生成的情况。因此,不能为每个小部件制作单独的 reactive()
语句。但是,如果反应语句需要遍历所有小部件名称(或类似名称),我当然可以使用它。并且多个反应语句是可以的,只要它是一个固定的数量,而不是小部件数量的函数。
这似乎是一个非常简单的问题,所以当它成为我的障碍时,我感到很惊讶。我觉得解决方案真的很明显,我只是没有看到,所以如果是的话,我很抱歉把它变成一个新问题。但如有任何帮助,我们将不胜感激。
您可以使用 reactiveValues()
创建的反应值来存储上次使用的小部件的名称。稍后使用观察者跟踪每个小部件的 activity 并使用上次使用的小部件的名称更新反应值。
在下面的示例中,最后使用的小部件的名称存储在 last_updated_widget$v
中,并且每次更改时都会激活 verbatimTextOutput
。您可以在服务器的任何地方使用 last_updated_widget$v
。
library(shiny)
runApp(list(
ui = shinyUI(
fluidPage(
textInput('txt_a', 'Input Text A'),
textInput('txt_b', 'Input Text B'),
verbatimTextOutput("showLast")
)
),
server = function(input, output, session) {
last_updated_widget <- reactiveValues( v = NULL)
observe ({
input$txt_a
last_updated_widget$v <- "txt_a"
})
observe ({
input$txt_b
last_updated_widget$v <- "txt_b"
})
output$showLast <- renderPrint({
last_updated_widget$v
})
}
))
这是一个可行的解决方案,但由于嵌套 observe()
,它看起来有点笨拙。我不确定有什么更好的方法,但可能会有更好的方法。
基本上,使用 observe()
遍历所有可用输入,对于每个输入,使用另一个 observe()
,它只会在该输入更改时触发,并将变量设置为 id输入的。
runApp(shinyApp(
ui = shinyUI(
fluidPage(
textInput('txt_a', 'Input Text A'),
textInput('txt_b', 'Input Text B'),
uiOutput('txt_c_out'),
verbatimTextOutput("show_last")
)
),
server = function(input, output, session) {
output$txt_c_out <- renderUI({
textInput('txt_c', 'Input Text C')
})
values <- reactiveValues(
lastUpdated = NULL
)
observe({
lapply(names(input), function(x) {
observe({
input[[x]]
values$lastUpdated <- x
})
})
})
output$show_last <- renderPrint({
values$lastUpdated
})
}
))