gpt4 book ai didi

r - 无功值 R Shiny 的多个输入

转载 作者:行者123 更新时间:2023-12-03 18:23:58 37 4
gpt4 key购买 nike

对于我正在构建的 Shiny 应用程序的一部分,我需要让用户选择一个目录。目录路径存储在一个 react ​​变量中。目录可以由用户从文件窗口中选择,也可以由 textInput 手动输入路径。 .我已经想出了如何做到这一点,但我不明白为什么我的解决方案有效!工作应用程序的最小示例:

library(shiny)

ui <- fluidPage(
actionButton("button1", "First Button"),
textInput("inText", "Input Text"),
actionButton("button2", "Second Button"),
textOutput("outText"),
textOutput("outFiles")
)

server <- function(input, output) {
values <- reactiveValues(inDir = NULL)
observeEvent(input$button1, {values$inDir <- tcltk::tk_choose.dir()})
observeEvent(input$button2, {values$inDir <- input$inText})
inPath <- eventReactive(values$inDir, {values$inDir})
output$outText <- renderText(inPath())
fileList <- reactive(list.files(path=inPath()))
output$outFiles <- renderPrint(fileList())
}

shinyApp(ui, server)

我尝试的第一件事就是使用 eventReactive并将两个输入源分配给无功变量:
server <- function(input, output) {
inPath <- eventReactive(input$button1, {tcltk::tk_choose.dir()})
inPath <- eventReactive(input$button2, {input$inText})
output$outText <- renderText(inPath())
fileList <- reactive(list.files(path=inPath()))
output$outFiles <- renderPrint(fileList())
}

据我所知,这样做的效果是只有一个按钮可以执行任何操作。我真的不明白为什么这不起作用。我认为会发生的是,按下的第一个按钮会创建 inPath然后后续推送将更新值并触发对相关值的更新(此处为 output$outText )。那么这里到底发生了什么?

我尝试的第二件事几乎就在那里,基于 this answer :
server <- function(input, output) {
values <- reactiveValues(inDir = NULL)
observeEvent(input$button1, {values$inDir <- tcltk::tk_choose.dir()})
observeEvent(input$button2, {values$inDir <- input$inText})
inPath <- reactive({if(is.null(values$inDir)) return()
values$inDir})
output$outText <- renderText(inPath())
fileList <- reactive(list.files(path=inPath()))
output$outFiles <- renderPrint(fileList())
}

这可以正常工作,只是它显示了 list.files 的“错误:无效的‘路径’参数”消息。 .我认为这可能意味着 fileList正在评估 inPath = NULL .为什么在我使用 reactive 时会发生这种情况而不是 eventReactive ?

谢谢!

最佳答案

你可以去掉 inPath react 性,只需使用 values$inDir反而。
req()您将等到值可用。否则你会得到同样的错误(无效的“路径”参数)。
reactive立即触发,而 eventReactive将等到给定的事件发生并调用 eventReactive。

if(is.null(values$inDir)) return()将无法正常工作,因为如果 values$inDir 它将返回 NULL为 NULL,然后传递给 list.files .和 list.files(NULL)给出错误:invalid 'path' argument .

将其替换为 req(values$inDir)你不会得到那个错误。

还有你的例子 2 inPath - eventReactive 不起作用,因为第一个会被第二个覆盖,所以 input$button1不会触发任何东西。

library(shiny)

ui <- fluidPage(
actionButton("button1", "First Button"),
textInput("inText", "Input Text"),
actionButton("button2", "Second Button"),
textOutput("outText"),
textOutput("outFiles")
)

server <- function(input, output) {
values <- reactiveValues(inDir = NULL)

observeEvent(input$button1, {values$inDir <- tcltk::tk_choose.dir()})
observeEvent(input$button2, {values$inDir <- input$inText})
output$outText <- renderText(values$inDir)

fileList <- reactive({
req(values$inDir);
list.files(path=values$inDir)
})

output$outFiles <- renderPrint(fileList())
}

shinyApp(ui, server)

您也可以使用 eventReactivebutton1和一个 observeEventbutton2 ,但请注意,您需要一个额外的 observe({ inPath() })使其工作。我更喜欢上面的解决方案,因为它更清楚发生了什么并且代码更少。
server <- function(input, output) {
values <- reactiveValues(inDir = NULL)

inPath = eventReactive(input$button1, {values$inDir <- tcltk::tk_choose.dir()})
observe({
inPath()
})

observeEvent(input$button2, {values$inDir <- input$inText})
output$outText <- renderText(values$inDir)

fileList <- reactive({
req(values$inDir);
list.files(path=values$inDir)
})

output$outFiles <- renderPrint(fileList())
}

并说明为什么 if(is.null(values$inDir)) return()不起作用,请考虑以下功能:
test <- function() { if (TRUE) return() }
test()

虽然 如果 -condition 计算结果为 ,仍然会有一个返回值(在这种情况下 NULL ),它将被传递给以下函数,在你的情况下是 list.files ,这将导致错误。

关于r - 无功值 R Shiny 的多个输入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50957611/

37 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com