2017-02-20 2 views
1

В моем приложении, пользователь должен выбрать папку, и в этой папке он должен выбрать файл (суффикс имени файла «.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: неверный «путь» аргумент это мой код-

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) 

Любая помощь будет оценена

+0

Просто убедитесь, что вы хотите, чтобы пользователь мог выбрать файл на стороне сервера или выбрать файл со своего компьютера? –

+0

, откуда мой скрипт, на сервере –

+0

Так что 'fileInput()' не то, что вы ищете тогда: http://shiny.rstudio.com/reference/shiny/latest/fileInput.html –

ответ

1

Поскольку вы используете eventReactive() будет отображаться только список папок и даже после выбора папки кто-то нажал о n кнопку «Обновить». Вы можете избежать этого с помощью ignoreNULL = FALSE:

wd_folders <- eventReactive(input$refresh_wd, { 
    basename(list.dirs(recursive = FALSE)) 
    }, ignoreNULL = FALSE) 

Если вы не сделаете этого, значение wd_folders() будет NULL, чтобы начать с, так что ваше состояние для conditionalPanel выполнено (это не «выберите папку»), и, следовательно, ваше приложение пытается прочитать файлы в каталоге 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

Спасибо! теперь работает отлично. Я прочитаю о 'validate (need())' перед тем, как начать использовать его. большое спасибо! –

1

Вот минимальный пример, который автоматически обновляет папки каждые 5 секунд. Он по-прежнему вызывает первоначальное предупреждение о том, что path недействителен по причинам, описанным в объяснениях @JoriMeys.

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) 
+0

Спасибо, я посмотрю, что ты тоже сделал. –