Je crée une application brillante qui nécessite qu'un utilisateur sélectionne un dossier sur la machine locale, qui contient les fichiers à traiter par l'application.
J'utilise une solution proposée ici . Cela fonctionne bien sur une machine locale, mais ne fonctionne pas si l'application est déployée sur un serveur shinyapps. L'auteur de cette solution a confirmé qu'elle était uniquement conçue pour fonctionner avec des applications Shiny locales, car elle effectue des appels OS Shell pour afficher une boîte de dialogue de répertoire.
Je me demande s'il existe une solution différente pour la boîte de dialogue de répertoire, qui fonctionnera sur les applications Shiny déployées (je déploie sur shinyapps.io).
Modifié: notez que je ne peux pas utiliser l'interface fileInput pour deux raisons:
multiple
activée.La structure des dossiers/fichiers n'est pas quelque chose que je peux changer, elle est téléchargée AS IS à partir d'un appareil médical et donc la seule chose que je peux attendre des utilisateurs est de spécifier le dossier parent et le reste devrait être fait à l'intérieur du code R.
Il s'agit d'un exemple de travail basé sur l'utilisation de l'attribut "webkitdirectory". Pour le moment, l'attribut est pris en charge par Chrome, Opera et Safari (mobile et ordinateur de bureau) et devrait être pris en charge dans Firefox 49 pour être publié en septembre. Pour en savoir plus ici . Il fonctionne également avec les sous-répertoires.
Cela nécessite l'utilisation du mot-clé tags dans ui.R. Je l'ai testé en téléchargeant trois fichiers csv contenant chacun trois nombres séparés par un coma. Testé localement et sur shinyapps.io avec Chrome et Opera. Voici le code:
ui.R
library(shiny)
library(DT)
shinyUI(tagList(fluidPage(theme = "bootstrap.css",
includeScript("./www/text.js"),
titlePanel("Folder content upload"),
fluidRow(
column(4,
wellPanel(
tags$div(class="form-group shiny-input-container",
tags$div(tags$label("File input")),
tags$div(tags$label("Choose folder", class="btn btn-primary",
tags$input(id = "fileIn", webkitdirectory = TRUE, type = "file", style="display: none;", onchange="pressed()"))),
tags$label("No folder choosen", id = "noFile"),
tags$div(id="fileIn_progress", class="progress progress-striped active shiny-file-input-progress",
tags$div(class="progress-bar")
)
),
verbatimTextOutput("results")
)
),
column(8,
tabsetPanel(
tabPanel("Files table", dataTableOutput("tbl")),
tabPanel("Files list", dataTableOutput("tbl2"))
)
)
)
),
HTML("<script type='text/javascript' src='getFolders.js'></script>")
)
)
server.R
library(shiny)
library(ggplot2)
library(DT)
shinyServer(function(input, output, session) {
df <- reactive({
inFiles <- input$fileIn
df <- data.frame()
if (is.null(inFiles))
return(NULL)
for (i in seq_along(inFiles$datapath)) {
tmp <- read.csv(inFiles$datapath[i], header = FALSE)
df <- rbind(df, tmp)
}
df
})
output$tbl <- DT::renderDataTable(
df()
)
output$tbl2 <- DT::renderDataTable(
input$fileIn
)
output$results = renderPrint({
input$mydata
})
})
text.js
window.pressed = function(){
var a = document.getElementById('fileIn');
if(a.value === "")
{
noFile.innerHTML = "No folder choosen";
}
else
{
noFile.innerHTML = "";
}
};
getFolders.js
document.getElementById("fileIn").addEventListener("change", function(e) {
let files = e.target.files;
var arr = new Array(files.length*2);
for (let i=0; i<files.length; i++) {
//console.log(files[i].webkitRelativePath);
//console.log(files[i].name);
arr[i] = files[i].webkitRelativePath;
arr[i+files.length] = files[i].name;
}
Shiny.onInputChange("mydata", arr);
});
Faites-moi savoir si cela aide.
Avez-vous essayé le package shinyFiles
? Il y a un widget qui vous permet de choisir un répertoire. En sortie, vous obtenez le chemin de ce répertoire que vous pouvez à son tour utiliser pour accéder aux fichiers. Voici un exemple de fonctionnement.
library(shiny)
library(shinyFiles)
shinyServer(function(input, output, session) {
# dir
shinyDirChoose(input, 'dir', roots = c(home = '~'), filetypes = c('', 'txt'))
dir <- reactive(input$dir)
output$dir <- renderPrint(dir())
# path
path <- reactive({
home <- normalizePath("~")
file.path(home, paste(unlist(dir()$path[-1]), collapse = .Platform$file.sep))
})
# files
output$files <- renderPrint(list.files(path()))
})
library(shiny)
library(shinyFiles)
shinyUI(fluidPage(sidebarLayout(
sidebarPanel(
shinyDirButton("dir", "Chose directory", "Upload")
),
mainPanel(
h4("output$dir"),
verbatimTextOutput("dir"), br(),
h4("Files in that dir"),
verbatimTextOutput("files")
)
)))
J'espère que cela t'aides.