2015-12-23 5 views
4

Я следую за simple file upload example из блестящей галереи, но с небольшой модификацией. Мне нужно изменить файлы csv локально и увидеть изменения, отраженные в пользовательском интерфейсе. Однако я считаю, что это невозможно, если мы не опросим какие-либо изменения в источнике.Повторно загрузите тот же файл shiny R

Поэтому я упрощаю проблему, позволяя повторно загружать файл. Но это также не происходит в Блестящем. После загрузки файла «file1.csv» я не могу загрузить тот же файл снова. Мне нужно загрузить другой файл «file2.csv», а затем еще раз исходный файл «file1.csv».

Это заняло много времени, и мне интересно, есть ли у кого-либо такая проблема и, возможно, нашли решение для этого.

ответ

3

Добавление jquery для очистки значения fileInput делает трюк.

... 
fileInput("csvInput", "Upload CSV file", multiple = TRUE, 
       accept=c('text/csv', 
         'text/comma-separated-values,text/plain', 
         '.csv')), 
tags$script('$("#csvInput").on("click", function() { this.value = null; });'), 
... 
+0

Ничего себе этот трюк гораздо проще применять. Круто. – Kai

1

На самом деле это один из недостатков модуля Shiny fileInput: он остается неподвижным, если тот же файл был выбран снова, и нет встроенной опции опции force-upload.


Для принудительного повторного загрузки, основная идея:

  1. После каждого загрузки времени, сохранить загруженные данные в reactiveValues в качестве хранилища.
  2. Применить новый fileInput для замены оригинального
  3. Показать успешную загрузку сообщения под новым fileInput для лучшего удобства пользователей.

В ui.R, используя

uiOutput('fileImport') 

В server.R:

# reactive storage 
v <- reactiveValues() 
# fileInput index 
v$fileInputIndex <- 1 

updateFileInput <- function (name = NULL){ 
    # update output with a new fileInput module 
    output$fileImport <- renderUI({ 
    index <- isolate(v$fileInputIndex) 
    result <- div() 
    result <- tagAppendChild(
     result, 
     fileInput(paste0('file', index), 'Choose CSV File',accept=c('text/csv','text/comma-separated-values,text/plain','.csv')) 
    ) 
    # show a message of successful uploading 
    if(!is.null(name)){ 
     result <- tagAppendChild(
     result, 
     div(name," upload complete") 
    ) 
    } 
    result 

    }) 
} 

dataInputRaw <- reactive({ 
    # equals to `input$file1` when initialized 
    inFile <- input[[paste0('file', v$fileInputIndex)]] 

    # TICKY PART: 
    # 1. If initialized, `inFile` and `v$data` are both `NULL` 
    # 2. After each uploading, new `fileInput` is applied and 
    # we want to keep previous updated data. 
    # It also prevent recursive creation of new `fileInput`s. 
    if (is.null(inFile)){ 
    return(v$data) 
    } 

    # load as data frame 
    v$data <- data.frame(read.csv(inFile$datapath)) 

    # if file successfuly uploaded, increate the index 
    # then upload `fileInput` with successful message 
    if (!is.null(v$data)){ 
    v$fileInputIndex <- v$fileInputIndex + 1 
    updateFileInput(name = inFile$name) 
    } 

    # return data 
    v$data 
}) 

# init 
updateFileInput() 

Я проверил этот фрагмент кода, и она работает.

+0

Спасибо за ответ. Но я не могу использовать reactiveValues ​​(). Я использую функцию наблюдателя ({}), которая не очень хорошо сочетается с реактивной ({}) –

Смежные вопросы