I am trying to create a Shiny app that uploads a dynamic number of CSV files and display them through renderTable. I used the answer from this link for the dynamic fileInput. I added an eventReactive to read the CSV files and a renderUI for the dynamic number of tableOutputs. I don't get any errors when I run the code, so I don't know where the reactivity breaks.
Server:
shinyServer(function(input, output, session) {
output$fileInputs=renderUI({
n<-input$nfiles
html_ui = " "
for (i in 1:n){
html_ui <- paste0(html_ui, fileInput(inputId= paste0("fileupload",i), label=paste0("fileupload",i),accept = c("text/csv", "text/comma-separated-values,text/plain",".csv")) )
}
HTML(html_ui)
})
Reading <-eventReactive(input$Read, {
lst<-list()
n<-input$nfiles
for (i in 1:n){
file<-paste0("fileupload",i)
inFile<-input$file
if (is.null(inFile))
return(NULL)
lst[[i]] <- read.csv(inFile$datapath)
}
lst
})
output$fileoutputs <- renderUI({
n<-input$nfiles
for (i in 1:n){
output[[paste0("table",i)]] <- renderTable( Reading()$lst[[i]] )
tableOutput(paste0("table",i))
}
})
})
UI:
shinyUI(pageWithSidebar(
headerPanel('Variable files'),
sidebarPanel(
numericInput("nfiles", "number of files", value = 2, min = 1, step = 1),
uiOutput("fileInputs"),
actionButton("Read", "read")
),
mainPanel(
uiOutput("fileoutputs")
)
))
Related
I want to upload two csv files and print both tables out.
Here is the code I wrote:
library(shiny)
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
fileInput(inputId = "files", label = "Choose CSV File", multiple = TRUE,accept = c(".csv")
)
),
mainPanel(
fluidRow(tableOutput("Policy1")),
fluidRow(tableOutput("Policy2")),
)
)
)
server <- function(input, output) {
data <- reactiveValues(file1 = NULL,
file2 = NULL)
output$Policy1 <- renderTable({
if(!is.null(input$files$datapath[1]))
data$file1 <- read.csv(input$files$datapath[1], header = TRUE)
data$file1
})
output$Policy2 <- renderTable({
if(is.null(input$files$datapath[2])) {return(1)}
else{return(NULL)}
})
}
shinyApp(ui, server)
and for the output$Policy2 part, I want to test when the is.null(input$files$datapath[2]) is true. I thought it should be true when I only upload one file or don't upload anything but
if I only upload one csv file, it didn't print out the table 1, which means is.null(input$files$datapath[2]) is false in this case.I don't know why this is the case.
And as a result, if I change the code to ask shiny print two tables for me and only upload one file, there will be an error, here is the code:
library(shiny)
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
fileInput(inputId = "files", label = "Choose CSV File", multiple = TRUE,accept = c(".csv")
)
),
mainPanel(
fluidRow(tableOutput("Policy1")),
fluidRow(tableOutput("Policy2")),
)
)
)
server <- function(input, output) {
data <- reactiveValues(file1 = NULL,
file2 = NULL)
output$Policy1 <- renderTable({
if(!is.null(input$files$datapath[1]))
data$file1 <- read.csv(input$files$datapath[1], header = TRUE)
data$file1
})
output$Policy2 <- renderTable({
if(!is.null(input$files$datapath[2]))
data$file2 <- read.csv(input$files$datapath[2], header = TRUE)
data$file2
})
}
shinyApp(ui, server)
where I only change a little part and here is the error :
which I assume is because I should return NULL when only one file inputed in, how can I fix this problem, thanks for any help
The value won't be NULL if it's missing. It's better to check that there are enough values checking the length of the vector or something. For example
output$Policy2 <- renderTable({
if(!is.null(input$files) && length(input$files$datapath)>=2)
data$file2 <- read.csv(input$files$datapath[2], header = TRUE)
data$file2
})
I am trying to calculate the standard deviation of an Excel file loaded onto my Shiny App. I don't appear to be able to do so. When I put sd(output$contents) or sd(file1) it tends to crash the application. Here is what I have so far
For reference, the data I am uploading is univariate time series
I would be very grateful if someone would be able to help me out- I think it is a beginner problem! perhaps I am just viewing the file and not using it?
EDIT: the excel file always contains a single column of numbers, but the title and header may change. Therefore I would like to reference column A in the changing excel files.
ui <- fluidPage(
setBackgroundColor("ghostwhite"),
titlePanel(h1("title", style = "color:navy")),
p("subtitle"),
headerPanel(h3("Input data here", style = "color:navy")),
# Sidebar panel
sidebarLayout(
sidebarPanel( position =c("left"),
sliderInput("SL",
"ServiceScore",
min = 1.28, max = 3.09, value = 2.28),
numericInput("LT", "LT: weeks",0, min=0, max = 30),
fileInput('file1', 'MS, choose xlsx file',
accept = c(".xlsx")
),
br(),
actionButton("action_Calc", label = "Refresh & Calculate"), ),
# Main panel
mainPanel(h3( textOutput("SL"),
textOutput("LT"),
textOutput("SS"),
tableOutput('contents')
))))
server <- function(input, output) {
output$SL <- renderText({
paste("Your score", input$SL)})
output$LT <- renderText ({
paste( "Your LT is", input$LT)})
output$contents <- renderTable({
req(input$file1)
inFile <- input$file1
read_excel(inFile$datapath, 1)
})
values<- reactiveValues()
observe({
input$action_Calc
values$int<- isolate({
input$SL*sqrt(input$LT/4)*sd(**HERE IS WHERE I NEED THE SD of the EXCEL FILE**)
})})
output$SS <- renderText({paste("calculation is", values$int)})
}
shinyApp(ui, server)
Read the Excel file in a reactive conductor:
Data <- reactive({
req(input$file1)
inFile <- input$file1
read_excel(inFile$datapath, 1)
})
output$contents <- renderTable({
Data()
})
Now if you want the standard deviation of the first column:
values<- reactiveValues()
observe({
input$action_Calc
values$int <- isolate({
input$SL*sqrt(input$LT/4)*sd(Data()[[1]])
})
})
output$SS <- renderText({paste("calculation is", values$int)})
How can I create a shiny app with two dropdown menus with csv files from ./data folder then read those Csv and compare differences?
A user selects CSV from two dropdown menus then automatically generates differences
UI.R
library("shiny")
ui <- fluidPage(
fluidPage(
titlePanel("Automated Data Dictionary Comparison"),
sidebarLayout(
sidebarPanel(
selectInput(inputId = 'Dic1',
label = 'Choose First Data Dictionary:',
choices = list.files(path = "./data",
full.names = FALSE,
recursive = FALSE)),
selectInput(inputId = 'Dic2',
label = 'Choose Second Data Dictionary:',
choices = list.files(path = "./data",
full.names = FALSE,
recursive = FALSE))
),
mainPanel(
tableOutput('contents')
)
)
)
)
SERVER.R
Library(shiny)
library(dplyr)
server <- function(input, output) {
dataset <- reactive({
infile <- input$Dic1
if (is.null(infile)){
return(NULL)
}
read.csv(infile[[1]])
})
output$contents <- renderDataTable({
#x <- dataset()
Diff <- render_diff(diff_data(data_ref=input$DIC1, data = input$DIC2),
Diff
})
}
From what I can see here, what you are doing is that you are correctly creating your reactive dataset object dataset (for 1 of your input files though not both), but you are not using this later on, when you want to generate the differences table (which again needs to be a reactive component as it will be generated from 2 reactive ones - dataset1 and dataset2).
Something like this should do the trick though (wrap it inside the server function):
# Parse first file
dataset1 <- reactive({
infile <- input$Dic1
if (is.null(infile)){
return(NULL)
}
x <- read.csv(infile[[1]])
x
})
# Parse second file
dataset2 <- reactive({
infile <- input$Dic2
if (is.null(infile)){
return(NULL)
}
x <- read.csv(infile[[1]])
x
})
# Create comparison table (reactive as both of its elements are reactive)
diff <- reactive({
x <- render_diff(diff_data(data_ref=dataset1(), data=dataset2()))
x
})
#Output
output$contents <- renderDataTable({
diff()
})
Check the above and let me know how it goes for you.
I have a question regarding R shiny and the observ function. Is it possible to save the selected factors and the state of the work? For Example I created a programm which can choose colnames from the input data. After using bookmark and reopening the programm with the link in the browser the input data are loaded but the select factors of the colnames are reset. But I want to save the chosen colnames. Has anyone an idea? Thank you for your help!
ui <- function(request) {
fluidPage(
sidebarLayout(
sidebarPanel(
radioButtons(
"fileType_Input",
label = h5(""),
choices = list(".csv" = 1, ".xlsx" = 2),
selected = 1,
inline = TRUE
),
fileInput('file1', '' ),
selectInput("letters", label=NULL, factors, multiple = TRUE),
bookmarkButton()
),
mainPanel(
tableOutput("contents")
)
)
)
}
server <- function(input, output,session) {
myData <- reactive({
inFile <- input$file1
# Get the upload file
if (is.null(inFile)) {
return(NULL) }
if (input$fileType_Input == "1") {
read.csv2(inFile$datapath,
header = TRUE,
stringsAsFactors = FALSE)
} else {
read_excel(inFile$datapath)
}
})
observe({
if(is.null(input$letters)){
data <- myData()
if(is.null(data)){
}else{
factors <- colnames(data)
t$choices <- input$letters # append(u$choices,input$letters2)
updateSelectInput(session, "letters",
choices = factors #[!factors2 %in% u$choices)]
)}
}
})
#Display all input Data
output$contents <- renderTable(digits = NULL,{
df <-myData()
df
})
}
enableBookmarking("server")
shinyApp(ui, server)
You can save all needed inputs in a file, and then reapply them with functions like updateRadioButtons() and others.
Saving it to the file could look like this:
observeEvent(input$someRadioButton, {
states <- list()
states$someRadioButton <- input$someRadioButton
#you can save all the needed inputs like this
...
save(states, file = paste0(getwd(), "/myfile"))
})
I am pretty new to Shiny (and R) and struggling with exporting the plot I make in Shiny to a png-file.
I looked at these two threads but could not figure it out:
Save plots made in a shiny app
Shiny downloadHandler doesn't save PNG files
I manage to create the download button in the ui and the server seems to be doing everything I want it to do, too. When I hit the download button in the preview window, a pop up window asks me to specify the file location and name but no file is saved. When I do the same in a browser window, a png file is created but it is empty.
Any insight is much appreciated!
ui.R
library(shiny)
shinyUI(fluidPage(
titlePanel("This is a scatterplot"),
sidebarLayout(
sidebarPanel(
fileInput('datafile', 'Choose CSV file',
accept=c('text/csv', 'text/comma-separated-values,text/plain')),
uiOutput("varselect1"),
uiOutput("varselect2"),
downloadButton('downloadPlot', 'Download Plot')
),
mainPanel(
h4("Here is your scatterplot"),
plotOutput("plot1")
)
))
)
server.R
library(foreign)
shinyServer(function(session,input, output) {
DataInput <- reactive({
infile <- input$datafile
if (is.null(infile)) {
return(NULL)
}
read.csv(infile$datapath)
})
output$varselect1 <- renderUI({
if (identical(DataInput(), '') || identical(DataInput(),data.frame())) return(NULL)
cols <- names(DataInput())
selectInput("var1", "Select a variable:",choices=c("---",cols[3:length(cols)]), selected=("---"))
})
output$varselect2 <- renderUI({
if (identical(DataInput(), '') || identical(DataInput(),data.frame())) return(NULL)
cols <- names(DataInput())
selectInput("var2", "Select a variable:",choices=c("---",cols[3:length(cols)]), selected=("---"))
})
plotInput <- reactive({
a <- which(names(DataInput())==input$var1)
x_lab <- as.numeric(DataInput()[,a])
b <- which(names(DataInput())==input$var2)
y_lab <- as.numeric(DataInput()[,b])
main.text <- paste("Scatterplot of the variables",colnames(DataInput())[a],"and", colnames(DataInput())[b],sep = " ", collapse = NULL)
plot(x_lab, y_lab, main=main.text, xlab=colnames(DataInput())[a], ylab=colnames(DataInput())[b], xlim=c(min(x_lab),max(x_lab)*1.05), ylim=c(min(y_lab), max(y_lab)*1.05))
observations <- DataInput()[,1]
text(x_lab, y_lab, labels=observations, pos=3)
})
output$plot1 <- renderPlot({
print(plotInput())
})
output$downloadPlot <- downloadHandler(
filename = "Shinyplot.png",
content = function(file) {
png(file)
print(plotInput())
dev.off()
})
})
A workaround for this strange scenario was discussed on the shiny-discuss google group. What you can do is simply change your reactive plotInput statement into a normal function. Not sure why downloadHandler doesn't play nice with reactive objects.
# change
plotInput <- reactive({...})
# into this
plotInput <- function(){...}
You can also remove the print statement in the downloadHandler call:
output$downloadPlot <- downloadHandler(
filename = "Shinyplot.png",
content = function(file) {
png(file)
plotInput()
dev.off()
})