I would like to design a basic production planning features. Mainly, i try to do in shiny what i do in excel. I have a file that is uploaded by user. Then, user should adjust new quantity(s) which decreases the inventory level. -in one day, multiple adjustments-
*Day is taken from system date. * The new lines should be displayed.
here is the sample data : http://www.filedropper.com/data2_2
library(shiny)
shinyServer(function(input, output) {
output$table1 <- renderTable({
if (is.null(input$file1))
return(NULL)
read.csv(input$file1$datapath, header=TRUE, sep=";",
quote='')
})
addData <- observe({
if(input$action > 0) {
f (is.null(input$file1))
return(NULL)
read.csv(input$file1$datapath, header=TRUE, sep=";",
quote='')
`uploadedfile1` <- read.csv(input$file1$datapath, sep=";")
uploadedfile2 <- uploadedfile1
safetystock <- 585
newLine <- isolate(c(Sys.Date(), "provided by file", input$spotQuantity, inventory, safetystock, Location2))
isolate(uploadedfile2Plot <- rbind(as.matrix(uploadedfile2), unlist(newLine)))
uploadedfile2 Plot
}
})
})
shinyUI(fluidPage(
sidebarLayout(
sidebarPanel(
fileInput('file1', 'Choose File', accept=c('text/csv', 'text/comma-separated-values,text/plain', '.csv')),
numericInput("Quantity", "Enter Quantity",value=0),
actionButton("action","Confirm")
),
# Show a plot of the generated distribution
mainPanel(
tableOutput("table1")
)
)
))
Related
I would like to implement an App which takes a .csv file as input (the user selects the file from his computer), then I want to take this file as a parameter in a function "f" that I've implemented previously.
I can give you the ui.R and server.R
ui.R
library(shiny)
shinyUI(fluidPage(
sidebarLayout(
sidebarPanel(
fileInput("file",
"Put your portfolio data here",
accept=c(".csv")
)
),
mainPanel(tableOutput("table"))
)
))
server.R
library(shiny)
shinyServer(function(input, output) {
data <- reactive({
file1 <- input$file
if(is.null(file1)){return()}
read.csv2(file=file1$datapath)
})
#to view the data
output$table <- renderTable({
if(is.null(data())){return ()}
data()
})
})
Finally my function "f" is supposed to give a .csv file as output.
ui.R
library(shiny)
shinyUI(fluidPage(
sidebarLayout(
sidebarPanel(
fileInput("file",
"Put your portfolio data here",
accept=c(".csv")
),
downloadButton(download_data.csv, "Download File")
),
mainPanel(tableOutput("table"))
)
))
server.R
shinyServer(function(input, output) {
data <- reactive({
file1 <- input$file
if(is.null(file1)){return()}
read.csv2(file=file1$datapath)
})
#to view the data
output$table <- renderTable({
if(is.null(data())){return ()}
data()
})
# to download the tadata
output$download_data.csv <- downloadHandler(
filename = "download_data.csv",
content = function(file){
data <- data() # At this point you should have done the transformation
# to the data
write.csv(data, file, row.names = F)
}
)
})
I have been referencing the following post which has been tremendously helpful in helping me understand Rshiny functionality:
How can I update plot from rhandsontable with uploaded data, without clicking into the table first?
I am still having some trouble grasping the concept of "Observe" so that may be the issue here. I want to upload 2 csvs where one is static (saving it in a separate tab) and one that can be edited (with edits reflected in the corresponding plot after hitting a button). My end goal is to be able to plot these data sets together on the same axes, but for now, I am having difficulty getting my table display which makes me think it's not uploading properly. I am using the following code:
library(shiny)
library(rhandsontable)
#sample data
year <- substr(Sys.Date(),1,4)
empty_dat=as.data.frame(matrix(1,nrow = 3,ncol = 4,dimnames = list(c("Cat A", "Cat B", "Cat C"),
c(paste("May",year),paste("June",year),paste("July",year),
paste("August",year)))))
ui = fluidPage(sidebarLayout(
sidebarPanel(
#static data input
fileInput('file1_new', 'Choose CSV File'),
#reactive data inut
fileInput('file1', 'Choose CSV File'),
#display reactive data
rHandsontableOutput('contents'),
actionButton("go", "Plot Update"),
width=7
),
mainPanel(
tabsetPanel(
#plot reactive data first tab
tabPanel("Plot", plotOutput("plot1")),
#table static data second tab
tabPanel("Table", tableOutput("table"))
)
)
))
server = function(input, output) {
#static input
output$table <- renderTable({
inFile <- input$file_new
if (is.null(inFile))
return(NULL)
read.csv(inFile$datapath, header = input$header,
sep = input$sep, quote = input$quote)
})
indat <- reactiveValues(data=empty_dat)
#reactive input
observe({
inFile = input$file1
if (is.null(inFile))
return(NULL)
data1 = read.csv(inFile$datapath)
indat$data <- data1
})
observe({
if(!is.null(input$contents))
indat$data <- hot_to_r(input$contents)
})
output$contents <- renderRHandsontable({
rhandsontable(indat$data)
})
#***example uses only one column-why I attempt multiple columns (indat$data[,1:4],indat$data[],indat$data) I get an error
#update data when user hits button
test <- eventReactive(input$go, {
return(indat$data[,3])
})
output$plot1 <- renderPlot({
#plot updated data
plot(test(),type = "l")
})
}
shinyApp(ui, server)
Any help would be greatly appreciated.
I made few changes to the code, and now the second tab displays the static table.
I am not sure if this is what you want but here's the code. The changes that I made are below the code.
library(shiny)
library(rhandsontable)
#sample data
year <- substr(Sys.Date(),1,4)
empty_dat=as.data.frame(matrix(1,nrow = 3,ncol = 4,dimnames = list(c("Cat A", "Cat B", "Cat C"),
c(paste("May",year),paste("June",year),paste("July",year),
paste("August",year)))))
ui = fluidPage(sidebarLayout(
sidebarPanel(
#static data input
fileInput('file1_new', 'Choose CSV File'),
#reactive data inut
fileInput('file1', 'Choose CSV File'),
#display reactive data
rHandsontableOutput('contents'),
actionButton("go", "Plot Update"),
width=7
),
mainPanel(
tabsetPanel(
#plot reactive data first tab
tabPanel("Plot", plotOutput("plot1")),
#table static data second tab
tabPanel("Table", tableOutput("table"))
)
)
))
server = function(input, output) {
#static input
output$table <- renderTable({
inFile <- input$file1_new
if (is.null(inFile))
{return(mtcars)}
else{
read.csv(inFile$datapath)}
})
indat <- reactiveValues(data=empty_dat)
#reactive input
observe({
inFile = input$file1
if (is.null(inFile))
return(NULL)
data1 = read.csv(inFile$datapath)
indat$data <- data1
})
observe({
if(!is.null(input$contents))
indat$data <- hot_to_r(input$contents)
})
output$contents <- renderRHandsontable({
rhandsontable(indat$data)
})
#***example uses only one column-why I attempt multiple columns (indat$data[,1:4],indat$data[],indat$data) I get an error
#update data when user hits button
test <- eventReactive(input$go, {
return(indat$data[,3])
})
output$plot1 <- renderPlot({
#plot updated data
plot(test(),type = "l")
})
}
shinyApp(ui, server)
So in the part where you do the renderTable, the variable name was slightly wrong :p, and in the read.csv, there were too many arguments.
output$table <- renderTable({
inFile <- input$file1_new
if (is.null(inFile))
{return(mtcars)}
else{
read.csv(inFile$datapath)}
})
Please let me know if this works for you... Cheers!
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).
I am trying to upload a file to Shiny to crunch it and then view it.
I already was able to create a table with a CSV document, but the output myData can't be used as an input for a boxplot or any other graph.
SERVER
shinyServer(function(input, output, session){
myData <- reactive({
inFile <- input$file1
if (is.null(inFile)) return(NULL)
data <- read.csv(inFile$datapath, header = TRUE)
data
})
output$contents <- renderTable({
myData()
})
}
UI
library(shiny)
write.csv(data.frame(a = 1:10, b = letters[1:10]), 'test.csv')
shinyUI(fluidPage(
titlePanel("Uploading Files"),
sidebarLayout(
sidebarPanel(
fileInput('file1', 'Choose CSV File',
accept=c('text/csv',
'text/comma-separated-values,text/plain',
'.csv'))
),
mainPanel(
tableOutput('contents'),
plotOutput('distPlot')
)
)
)
)
How can I use the data from the file I uploaded out of the function myData?
You should use the functions renderDataTable and dataTableOutput from the DT package for rendering your tables. Your code works fine like this:
library(shiny)
library(DT)
server <- function(input, output, session){
myData <- reactive({
inFile <- input$file1
if (is.null(inFile)) return(NULL)
data <- read.csv(inFile$datapath, header = TRUE)
data
})
output$contents <- DT::renderDataTable({
DT::datatable(myData())
})
}
write.csv(data.frame(a = 1:10, b = letters[1:10]), 'test.csv')
ui<- shinyUI(fluidPage(
titlePanel("Uploading Files"),
sidebarLayout(
sidebarPanel(
fileInput('file1', 'Choose CSV File',
accept=c('text/csv',
'text/comma-separated-values,text/plain',
'.csv'))
),
mainPanel(
DT::dataTableOutput('contents'),
plotOutput('distPlot')
)
)
)
)
shinyApp(ui,server)
Also see the article below:
It is also possible to have an user upload csv's to your Shiny app. The code below shows a small example on how this can be achieved. It also includes a radioButton input so the user can interactively choose the separator to be used.
library(shiny)
library(DT)
# Define UI
ui <- shinyUI(fluidPage(
fileInput('target_upload', 'Choose file to upload',
accept = c(
'text/csv',
'text/comma-separated-values',
'.csv'
)),
radioButtons("separator","Separator: ",choices = c(";",",",":"), selected=";",inline=TRUE),
DT::dataTableOutput("sample_table")
)
)
# Define server logic
server <- shinyServer(function(input, output) {
df_products_upload <- reactive({
inFile <- input$target_upload
if (is.null(inFile))
return(NULL)
df <- read.csv(inFile$datapath, header = TRUE,sep = input$separator)
return(df)
})
output$sample_table<- DT::renderDataTable({
df <- df_products_upload()
DT::datatable(df)
})
}
)
# Run the application
shinyApp(ui = ui, server = server)
In my app, the user can upload their file as the input data (using file upload widget). If they don't have their data, I provide some demo data (user can choose demo data by clicking actionButton).
How do I make a variable = the upload OR the demo, whichever is later? Any help is appreciated.
server.R
library(shiny)
DemoData = data.frame('Col.1'=c('Demo','Demo'),
'Col.2'=c('Data','Data'))
shinyServer(function(input, output) {
# option 1: use demo data
getDemo = eventReactive(input$Demo,{
DemoData
})
# option 2: user upload data
getUpload = reactive({
inFile = input$file
if (is.null(inFile)) return(NULL)
read.csv(inFile$datapath)
})
# need getData() to be option 1 or 2, whichever happened later
# should respond to multiple times of changing between option 1 and 2
getData = # ??? getDemo() or getUpload(), whichever is later
# show the data
output$InputData = renderDataTable({
as.data.frame( getData() )
})
})
ui.R
library(shiny)
shinyUI(fluidPage(
titlePanel(h2("Hello Shiny")),
sidebarLayout(
sidebarPanel(
fileInput('file',
'Choose CSV File (two columns: Town and State)',
accept=c('text/csv',
'text/comma-separated-values,text/plain',
'.csv')
),
actionButton('Demo', 'Use Demo Data')
),
mainPanel(
tabsetPanel(
tabPanel(title=h4('Data'),
column(5, tags$h3('Input Data'), dataTableOutput('InputData'))
)
)
)
)
))
UserData.R (maybe make it easier for you to test)
getwd()
setwe()
UserData = data.frame('Col.1'=c('User','User'),
'Col.2'=c('Data','Data'))
write.csv(UserData, file="UserData.csv", row.names=FALSE)
You can use observers, one to watch the demo button and one to watch for file uploads. Both update the same reactive data, so you see the effect of whichever happened last.
library(shiny)
DemoData <- data.frame('Col.1'=1:10,
'Col.2'=rnorm(10))
shinyApp(
shinyUI(fluidPage(
titlePanel(h2("Hello Shiny")),
sidebarLayout(
sidebarPanel(
fileInput('file',
'Choose CSV File (two columns: Town and State)',
accept=c('text/csv',
'text/comma-separated-values,text/plain',
'.csv')
),
actionButton('Demo', 'Use Demo Data')
),
mainPanel(
tabsetPanel(
tabPanel(title=h4('Data'),
column(5, tags$h3('Input Data'), tableOutput('InputData'))
)
)
)
)
)),
shinyServer(function(input, output) {
values <- reactiveValues() # store values to be changed by observers
values$data <- data.frame()
## Observer for uploaded file
observe({
inFile = input$file
if (is.null(inFile)) return(NULL)
values$data <- read.csv(inFile$datapath)
})
## Observer for demo data button
observe({
if (input$Demo > 0) # otherwise demo data shows on startup
values$data <- DemoData
})
## show the data
output$InputData = renderTable({
values$data
})
})
)