闪亮对象中的依赖关系

时间:2017-02-20 12:56:06

标签: r shiny

在我的应用中,用户需要选择一个文件夹,并且在该文件夹中他需要选择一个文件(文件名的后缀为' .seg')

此代码正常运行 -

library(shiny)
ui <- shinyUI(fluidPage(
    # select a folder
    column(2, absolutePanel(fixed = TRUE, width = '180px',
                            selectInput("pick_a_folder", label = '', selected='choose a folder',
                                        choices = setNames(as.list(c('choose a folder',
                                                                     basename(list.dirs(recursive = FALSE)))), 
                                                           c('choose a folder', 
                                                             basename(list.dirs(recursive = FALSE))))))),
    # select a file
    column(2, absolutePanel(fixed = TRUE, width = '180px', 
                            conditionalPanel(condition='!(input.pick_a_folder=="choose a folder")', 
                                             uiOutput('fileselection'))))
  ))
server <- shinyServer(function(input, output) {
  # dinamic file selection. find the files list after folder is choosen
  output$fileselection <- renderUI({
    selectInput('pick_file', '', selected = 'choose a file',
                choices=setNames(as.list(c('choose a file',basename(list.files(path=input$pick_a_folder,recursive=FALSE, pattern='\\.seg$')))), 
                                 c('choose a file',basename(list.files(path = input$pick_a_folder, recursive = FALSE, pattern='\\.seg$')))))
  })
})

shinyApp(ui = ui, server = server)

问题是,如果我在运行代码后将文件夹添加到工作目录,它将不会出现。 所以我尝试将文件夹选择移动到服务器,并使其依赖于刷新按钮,但是我收到错误

  

list.files中的错误:无效&#39;路径&#39;争论   这是我的代码 -

library(shiny)
ui <- shinyUI(fluidPage(
  # refresh butten for root directory
  column(1, absolutePanel(fixed=TRUE, actionButton("refresh_wd", "refresh"))),

  # select a folder
  column(2, absolutePanel(fixed = TRUE, width = '180px', uiOutput('folderselection'))),

  # select a file
  column(2, absolutePanel(fixed = TRUE, width = '180px', 
                          conditionalPanel(condition='!(input.pick_a_folder=="choose a folder")', 
                                           uiOutput('fileselection'))))
  ))

server <- shinyServer(function(input, output) {
  # refresh root directory
  wd_folders <- eventReactive(input$refresh_wd, {
    basename(list.dirs(recursive = FALSE))
  })

  output$folderselection <- renderUI({
    selectInput('pick_a_folder', '', selected = 'choose a folder',
                choices = setNames(as.list(c('choose a folder', wd_folders())),
                                   c('choose a folder', wd_folders())))
  })

  # dinamic file selection. find the file list after folder is choosen
  output$fileselection <- renderUI({
    selectInput('pick_a_file', '', selected = 'choose a file',
                choices=setNames(as.list(c('choose a file',basename(list.files(path=input$pick_a_folder,recursive=FALSE, pattern='\\.seg$')))), 
                                 c('choose a file',basename(list.files(path = input$pick_a_folder, recursive = FALSE, pattern='\\.seg$')))))
  })
})

shinyApp(ui = ui, server = server)

任何帮助将不胜感激

2 个答案:

答案 0 :(得分:1)

因为您使用eventReactive()文件夹列表,所以只有在有人点击“刷新”后才能显示文件夹选择。按钮。您可以使用ignoreNULL = FALSE

来避免这种情况
wd_folders <- eventReactive(input$refresh_wd, {
    basename(list.dirs(recursive = FALSE))
  }, ignoreNULL = FALSE)

如果你不这样做,那么wd_folders()的价值将为NULL,因此你conditionalPanel的条件已经满足(它不是&#34} ;选择一个文件夹&#34;)因此您的应用程序尝试读取目录中的文件为NULL。这会给你错误。

如果您想要更安全,可以将validate(need())添加到UI渲染中,例如:

output$fileselection <- renderUI({
    validate(need(input$pick_a_folder, label = "Pick a folder first"))
    validate(need(dir.exists(input$pick_a_folder),
                  label = "Something went wrong. Contact me."))
    selectInput('pick_a_file', '', selected = 'choose a file',
                ...)
  })

这不是解决问题所必需的,但我发现它在Shiny中是一种很好的做法。

答案 1 :(得分:1)

这是一个每5秒自动刷新文件夹的最小示例。 由于@JoriMeys解释的原因,它仍然会产生关于path无效的初始警告。

library(shiny)
ui <- shinyUI(fluidPage(

    column(1,
           absolutePanel(fixed=TRUE,

                         textOutput('wd'),

                         uiOutput('folderselection'),
                         conditionalPanel(
                             condition='!(input.pick_a_folder=="choose a folder")', 
                             uiOutput('fileselection'))
           )
    )
)
)


server <- shinyServer(function(input, output) {

    output$wd <- renderText(basename(
        list.files(path = input$pick_a_folder,
                   recursive=FALSE)
    )
    )
    button <- reactiveTimer(intervalMs = 5000)
    # refresh root directory
    wd_folders <- reactive({
        button()
        basename(list.dirs(recursive = FALSE))
    })

    output$folderselection <- renderUI({
        selectInput('pick_a_folder', '',
                    choices = c('choose a folder', wd_folders()
                    )
        )
    })

    # dinamic file selection. find the file list after folder is choosen
    output$fileselection <- renderUI({
        selectInput('pick_a_file', '', 
                    selected = 'choose a file',
                    choices=c('choose a file',
                              basename(list.files(path = input$pick_a_folder,recursive=FALSE))))
    })
})
shinyApp(ui = ui, server = server)