I saved the path of a user-defined folder with shinyDirChoose. Now I want to upload files from that user's folder, but I cannot figure out how to do it.
1) All on the server end?
2) Feeding the file paths to fileInput somehow?
This is how I construct the file paths for the three files that should be uploaded.
### ui end, to browse to desired folder
ui = fluidPage(shinyDirButton('directory', 'Folder select', 'Please select a folder'))
### extracting the folder path
server = function(input, output, session) {
volumes <- getVolumes()
shinyDirChoose(input, 'directory', roots=volumes, session=session)
path1 <- reactive({
return(print(parseDirPath(volumes, input$directory)))
})
### constructing the 3 file paths
datpat <- renderText({
req(nchar(path1())>0)
datpat <- paste0(path1(),"/data.csv")
})
vispat <- renderText({
req(nchar(path1())>0)
vispat <- paste0(path1(),"/visit.csv")
})
statpat <- renderText({
req(nchar(path1())>0)
statpat <- paste0(path1(),"/statvisit.csv")
})
So now I have these paths, but how can I use them to upload the related content to the server? A simple read.csv unfortunately does not do the trick.
EDIT - but not there yet...
Working further with the great help #SBista provided, I think I'm approaching my goal, but see below code...
volumes <- getVolumes()
shinyDirChoose(input, 'directory', roots=volumes, session=session)
path1 <- reactive({
return(print(parseDirPath(volumes, input$directory)))
})
observe({
if(!is.null(path1)){
### vis1
vis1 <- reactive({
datpat <- paste0(path1(),"/visit.csv")
vis <- read.csv(datpat, header = input$header, sep = input$sep, quote = input$quote,
stringsAsFactors = FALSE)
vis
})
### dataruw1
dataruw1 <- reactive({
datpat <- paste0(path1(),"/data.csv")
dataruw <- read.csv(datpat, header = input$header, sep = input$sep, quote = input$quote,
stringsAsFactors = FALSE)
dataruw
})
}
})
Unfortunately, dataruw1 and vis1 do not seem to be generated, as I get a 'could not find function' error when trying to use the actual data with dataruw1() and vis1(). What am I missing? Any idea? Thanks a lot in advance!
I have modified your app to demonstrate that you can use read.csv to upload the file. For demonstration I am reading only one file from the folder and displaying the read data frame in a datatable.
library(shiny)
library(shinyFiles)
### ui end, to browse to desired folder
ui = fluidPage(shinyDirButton('directory', 'Folder select', 'Please select a folder'),
tableOutput(outputId = "datpat")
)
### extracting the folder path
server = function(input, output, session) {
volumes <- getVolumes()
shinyDirChoose(input, 'directory', roots=volumes, session=session)
path1 <- reactive({
return(print(parseDirPath(volumes, input$directory)))
})
### constructing the 3 file paths
observe({
if(!is.null(path1)){
output$datpat <- renderTable({
req(nchar(path1())>0)
datpat <- paste0(path1(),"/data.csv")
dat <- read.csv(datpat)
dat
})
}
})
}
shinyApp(ui = ui, server = server)
Hope it helps!
Happy to have found a solution! Big thanks to SBista once more, even though I did it a bit differently. The below code is not just a chunk (as in my original post) but fully functional, provided you browse to a folder that contains a data.csv file.
library(shiny)
library(shinyFiles)
library(htmltools)
##############################################################################
ui = navbarPage(
HTML("Title"),
tabPanel(HTML("<font size=3>Start</font>"),
sidebarPanel(width = 2,
shinyDirButton('directory', 'Folder select', 'Please select a folder'),
checkboxInput('header', 'Header', TRUE),
radioButtons('sep', 'Separator', c(Comma=',',Semicolon=';',Tab='\t'), selected=';'),
radioButtons('quote', 'Quote', c(None='','Double Quote'='"','Single Quote'="'"), selected='"')),
mainPanel(
fluidRow(
column(6, tags$b(textOutput("text")))),
tags$hr(),
fluidRow(
column(6, dataTableOutput("table"))
)
)
)
)
server = function(input, output, session) {
volumes <- getVolumes()
shinyDirChoose(input, 'directory', roots=volumes, session=session)
path1 <- reactive({
return(print(parseDirPath(volumes, input$directory)))
})
dataruw1 <- eventReactive(input$directory, {
datpat <- paste0(path1(),"/data.csv")
dataruw <- read.csv(datpat, header = input$header, sep = input$sep, quote = input$quote,
stringsAsFactors = FALSE)
dataruw
})
output$text <- renderText({
path1()
})
output$table <- renderDataTable({
dataruw1()
})
}
shinyApp(ui = ui, server = server, options = list(launch.browser=TRUE))
Related
I am trying to built a shiny app, which allows the user to
select a local directory
select a csv from a list of available *.csv files in the folder
display the table / work with it.
The app loads a csv, but only for files with a static filename (see datpat static example). I assume the path to the file is the problem. The path to the directory seems to be ok. Also, the app should be accessed online (most likely own server), if this makes a difference.
This is a minimal code, which hopefully helps finding the error. You just have to navigate to a folder, where .csv files are. This example works if you choose a folder with a csv file named "data.csv".
Thanks a lot for your help!
library(shiny)
library(shinyFiles)
library(htmltools)
##############################################################################
ui = navbarPage(
HTML("Title"),
tabPanel(HTML("<font size=3>Start</font>"),
sidebarPanel(width = 2,
shinyDirButton('directory', 'Folder select', 'Please select a folder'),
checkboxInput('header', 'Header', TRUE),
radioButtons('sep', 'Separator', c(Comma=',',Semicolon=';',Tab='\t'), selected=';'),
radioButtons('quote', 'Quote', c(None='','Double Quote'='"','Single Quote'="'"), selected='"'),
uiOutput("csv_select"), #button to select files
),
mainPanel(
fluidRow(
column(6, tags$b(textOutput("text")))),
tags$hr(),
fluidRow(
column(6, dataTableOutput("table"))
)
)
)
)
server = function(input, output, session) {
volumes <- c(Home = fs::path_home(), "R Installation" = R.home(), getVolumes()())
shinyDirChoose(input, 'directory', roots=volumes, session=session)
path1 <- reactive({
return(print(parseDirPath(volumes, input$directory)))
})
### Select mp4 files within directory
output$csv_select <- renderUI({
csvs <- list.files(parseDirPath(volumes, input$directory),pattern=c(".csv"),recursive = F,full.names=T)
selectInput("csv_select","csv-ography",choices=basename(csvs))
})
file1 <- reactive({
return(print(input$csv_select))
})
dataruw1 <- eventReactive(input$directory, {
#datpat <- paste0(path1(),"/",file1()) # dynamic case, which selects file from folder --> does not work
datpat <- paste0(path1(),"/","data.csv") # static case, which works after directory selection
dataruw <- read.csv(datpat, header = input$header, sep = input$sep, quote = input$quote,
stringsAsFactors = FALSE)
dataruw
})
output$text <- renderText({
paste0(path1(),"/",file1())
})
output$table <- renderDataTable({
dataruw1()
})
}
shinyApp(ui = ui, server = server, options = list(launch.browser=TRUE))
I am trying to dynamically select directory from the computer where files are stored. Currently there is a sas dataset named 'sample' stored under my win10 PC desktop.
I would like to print out the first 10 observations of the sample dataset I read into, but it is not working without showing any error.
library(shiny)
library(shinyFiles)
library(haven)
library(DT)
ui<-fluidPage(sidebarLayout(
sidebarPanel(
shinyDirButton("dir", "Chose directory", "Upload")
),
mainPanel(
DT::dataTableOutput("sasdat")
)
))
server <- function(input,output,session){
dir <- reactive(input$dir)
shinyDirChoose(input, 'dir', roots=c(name=getwd()), session=session)
path1 <- reactive({
return(print(parseDirPath(volumes, input$dir)))
})
data1 <- eventReactive(input$path1, {
sample <- data.frame(read_sas(paste0(path1, "sample.sas7bdat")))
sample
})
output$sasdat = DT::renderDataTable({
head(data1(),10)
})
}
shinyApp(ui = ui, server = server)
Try this
library(shiny)
library(shinyFiles)
library(haven)
library(DT)
ui<-fluidPage(sidebarLayout(
sidebarPanel(
shinyDirButton("dir", "Chose directory", "Upload")
),
mainPanel(
DTOutput("sasdat")
)
))
server <- function(input,output,session){
#dir <- reactive(input$dir)
volumes <- getVolumes()
shinyDirChoose(input=input, 'dir', roots=volumes, session=session)
path1 <- reactive({
parseDirPath(volumes, input$dir)
})
data1 <- eventReactive(path1(), {
sample <- data.frame(haven::read_sas(paste0(path1(), "sample.sas7bdat")))
sample
})
output$sasdat = renderDT({
head(data1(),10)
})
}
shinyApp(ui = ui, server = server)
Or you can use fileInput to choose a file from your pc...
ui<-fluidPage(sidebarLayout(
sidebarPanel(
fileInput("sasdata1", "Choose a SAS dataset", multiple = FALSE, accept = ".sas7bdat"),
),
mainPanel(
DTOutput("sasdat")
)
))
server <- function(input,output,session){
data1 <- reactive({
req(input$sasdata1)
inData1 <- input$sasdata1
if (is.null(inData1)){ return(NULL) }
mydata1 <- haven::read_sas(inData1$datapath)
})
output$sasdat = renderDT({
head(data1(),10)
})
}
shinyApp(ui = ui, server = server)
I want shiny to upload and save data in the local disk, everything works fine except the saving part, below is the code, any help?
PS: There is no error message.
library(shiny)
library(tidyverse)
library(DT)
responsesDir <- file.path("c:/Users/Administrator/Desktop/11") #save at this dir
ui = fluidPage(
fileInput("FileInput", "File select"),
DT::dataTableOutput("table")
)
server = function(input, output, session) {
datasetInput <- eventReactive(input$FileInput, {
infile <- input$FileInput
read.csv(infile$datapath, header = TRUE)
})
data_save <- eventReactive(
input$FileInput,
{write.csv(datasetInput(), file = paste0(responsesDir, '/iris_set.csv'),
row.names = FALSE, quote = TRUE)}) #name iris_set.csv for example
output$table = DT::renderDataTable(datasetInput())
}
shinyApp(ui, server)
Finally after googling for couple of hours, I figured out by myself. Replacing the eventReactive from data_save line to observeEvent it worked.
library(shiny)
library(tidyverse)
library(DT)
responsesDir <- file.path("c:/Users/Vincent/Desktop/ls") #save at this dir
ui = fluidPage(
fileInput("FileInput", "File select"),
DT::dataTableOutput("table")
)
server = function(input, output, session) {
datasetInput <- eventReactive(input$FileInput, {
infile <- input$FileInput
read.csv(infile$datapath, header = TRUE)
})
data_save <- observeEvent(
input$FileInput,
{write.csv(datasetInput(), file = paste0(responsesDir, '/fuck_you.csv'),
row.names = FALSE, quote = TRUE)}) #name iris_set.csv for example
output$table = DT::renderDataTable(datasetInput())
}
shinyApp(ui, server)
I am very new to Shiny web app with R. I want to generate summary according to choice from checkboxGroupInput which i generated dynamically when browsing the CSV file. My problem is that when i want to convert from String to numeric that time it prints NA.
I am uploading my two files which are ui.r and server.r. I am trying since two days. If anyone help me then it will be very beneficial for me.
If i did anything wrong in my code then please suggest me right way.
ui.r
library(shiny)
library(shinythemes)
shinyUI(fluidPage(
theme = shinytheme("cyborg"),
themeSelector(),
# Application title
titlePanel("Data Analytics and Visualization Dashboard"),
sidebarLayout(
sidebarPanel(
fileInput('datafile', 'Choose CSV file',accept=c('text/csv', 'text/comma-
separated-values,text/plain')),
h5("Max file size to upload is 5 MB."),
radioButtons("sep", "Seperator", choices = c(Comma = ',', semicolon = ';',
tab = "\t", space = " " )),
#checkboxInput("header", "Header?")
br(),
h4("Select columns from CSV"),
uiOutput("toCol"),
br(),
h4("Summary"),
textOutput("sum")
# tableOutput("disp")
),
mainPanel(
numericInput("obs", "Enter the number of rows to display:", 5),
tableOutput("input_file"),
plotOutput("p")
)
)
))
server.r
library(shiny)
shinyServer(function(input, output,session) {
#This function is repsonsible for reading a csv file
output$input_file <- renderTable({
file_to_read = input$datafile
if(is.null(file_to_read))
{
return()
}
read.csv(file_to_read$datapath, sep = input$sep, nrows = input$obs))
})
#This function is repsonsible for loading in the selected file
filedata <- reactive({
infile <- input$datafile
if (is.null(infile)) {
# User has not uploaded a file yet
return(NULL)
}
read.csv(infile$datapath,nrows = input$obs)
})
#The following set of functions populate the column selectors
output$toCol <- renderUI({
df <-filedata()
if (is.null(df)) return(NULL)
items=names(df)
names(items)=items
checkboxGroupInput("to", "Columns",items)
})
observe({
# db <- gsub(",","",input$to)
# print(db)
# paste( intToUtf8(160), input$to, intToUtf8(160))
# print(summary(as.numeric(as.character( paste( " ", input$to, "
#"))))) })
print(summary(as.numeric( input$to) ))})
# output$sum <- renderPrint({
# summary(input$data.frame[,as.numeric(input$var)])
# })
# output$disp <- renderTable({
# input$to
# })
# output$summary1 <- renderPrint({
# sum <- as.numeric(as.character(input$to))
# summary(sum)
#})
})
This could be a starting point, although I dont recommend using this for a productive app, as the login-process is not really safe nor encrypted. It is based solely on text-data.
But you will have to put the ui in the server and render the page depending on the login status. So there are 2 renderUI but just 1 server-function. I dont know if you can have 2 different server-functions and redirect them. I think it all has to be in 1 server-function.
library(shiny)
username = "joe"
password = "joe123"
ui <- fluidPage(
uiOutput("ui")
)
server <- function(input, output, session) {
LOGGED <- reactiveValues(user = FALSE)
observeEvent(input$action, {
if ((input$name == username ) & (input$pass == password)) {
LOGGED$user = TRUE
} else {
LOGGED$user = FALSE
}
})
observe({
if (LOGGED$user == FALSE) {
output$ui <- renderUI({
tagList(
p(HTML("User is joe <br> and password is joe123")),
textInput("name", "Enter your username"),
passwordInput("pass", "Enter your password"),
actionButton("action", label = "Action")
)
})
} else if (LOGGED$user == TRUE) {
output$ui <- renderUI({
tagList(
h1("You are logged in.")
)
})
}
})
}
shinyApp(ui, server)
Like #Codeer said, there is no line in your code like this one summary(as.numeric(paste(input$to, “input$to”))). I edited your code, so all the uncommented lines dont appear, as its not necessary to show them.
In your example, your loading the csv file twice, which you can definitly avoid.
I moved the csv-loading into the reactive only. Then you can access the loaded file everywhere in your shiny-app. And i think in your print(summary()) statement, you're missing the data, as your only printing out the summary of the input$tovariable, which is only text and if you convert it to numeric you create NA-values.
So i rearranged your code a bit, and I think its behaving the way you intend it to.
library(shiny)
library(shinythemes)
ui <- {shinyUI(fluidPage(
theme = shinytheme("cyborg"),
themeSelector(),
titlePanel("Data Analytics and Visualization Dashboard"),
sidebarLayout(
sidebarPanel(
fileInput('datafile', 'Choose CSV file',accept=c('text/csv', 'text/comma-
separated-values,text/plain')),
h5("Max file size to upload is 5 MB."),
radioButtons("sep", "Seperator", choices = c(Comma = ',', semicolon = ';',
tab = "\t", space = " " )),
br(),
h4("Select columns from CSV"),
uiOutput("toCol"),
br(),
h4("Summary"),
textOutput("sum")
),
mainPanel(
numericInput("obs", "Enter the number of rows to display:", 5),
tableOutput("input_file"),
verbatimTextOutput("summary"),
plotOutput("p")
)
)
))}
server <- shinyServer(function(input, output,session) {
#This function is repsonsible for loading and reading a csv file
filedata <- reactive({
req(input$datafile)
infile <- input$datafile
if (is.null(infile)) {
# User has not uploaded a file yet
return(NULL)
}
read.csv(infile$datapath,nrows = input$obs, sep = input$sep)
})
output$input_file <- renderTable({
filedata()
})
#The following set of functions populate the column selectors
output$toCol <- renderUI({
df <- filedata()
if (is.null(df)) return(NULL)
items=names(df)
names(items)=items
checkboxGroupInput("to", "Columns",items)
})
output$summary <- renderPrint({
req(input$to)
data <- filedata()
print(summary(data[,input$to]))
})
})
shinyApp(ui, server)
The csv file is loaded in the reactive (filedata). In the renderTable, you just enter the reactive variable - filedata(). And in the observe, you call again the reactive variable and only print out the summary of the data in the clicked column (input$to).
While writing the app on my own computer, getVolumes() does what I want it to do: starting shinyDirChoose off at the root of my computer. This allows to browse to any folder on my computer.
After upload to shinyapps.io, however, I get the server's volumes.
How can I still get the local, user volumes instead of the server's, even when running the app from the server? If not possible, maybe the C: drive?
volumes <- getVolumes()
shinyDirChoose(input, 'directory', roots=volumes, session=session)
ui :
fluidRow(
fileInput('file1', 'Choose CSV File',multiple = TRUE,
accept=c('text/csv',
'text/comma-separated-values,text/plain',
'.csv'))
)
server :
output$contents <- renderTable({
# input$file1 will be NULL initially. After the user selects
# and uploads a file, it will be a data frame with 'name',
# 'size', 'type', and 'datapath' columns. The 'datapath'
# column will contain the local filenames where the data can
# be found.
inFile <- input$file1
if (is.null(inFile))
return(NULL)
read.csv(inFile$datapath, header = input$header)
})
these are directly from the help in Rstudio. I am using a linux machine, but I don't think that should make a difference.
This works! Many thanks to #Phi.
library(shiny)
ui = navbarPage(HTML("Title"),
tabPanel(HTML("<font size=3>Start</font>"),
sidebarPanel(width = 2,
fileInput('files', 'UPLOAD ManderMatcher EXPORT', multiple = TRUE, accept = c('text/csv','text/comma-separated-values','text/tab-separated-values','text/plain','.csv','.tsv')),
checkboxInput('header', 'Header', TRUE),
radioButtons('sep', 'Separator', c(Comma=',',Semicolon=';',Tab='\t'), selected=';'),
radioButtons('quote', 'Quote', c(None='','Double Quote'='"','Single Quote'="'"), selected='"'),
actionButton("Load", "APPLY DATA")
),
mainPanel(
tabsetPanel(
tabPanel("StaVst",
fluidRow(column(6, dataTableOutput("tabel1"))
)),
tabPanel("TabFsmSgh",
fluidRow(column(6, dataTableOutput("tabel2"))
)),
tabPanel("TabFsmVst",
fluidRow(column(6, dataTableOutput("tabel3"))
))
)
)
)
)
server = function(input, output, session) {
lst1 <- eventReactive(input$files, {
req(input$Load!=0)
lst <- list()
for(i in 1:length(input$files[,1])){
lst[[i]] <- read.csv(input$files[[i, 'datapath']], header = input$header, sep = input$sep, quote = input$quote,
stringsAsFactors =FALSE)
}
lst
})
output$tabel1 <- renderDataTable({
req(!is.null(input$files) & input$Load!=0)
lst1()[[1]]
})
output$tabel2 <- renderDataTable({
req(!is.null(input$files) & input$Load!=0)
lst1()[[2]]
})
output$tabel3 <- renderDataTable({
req(!is.null(input$files) & input$Load!=0)
lst1()[[3]]
})
}
shinyApp(ui = ui, server = server, options = list(launch.browser=TRUE))