getting data from excel sheet put them as dropdowns in shiny app - r

I have made an shiny app where I am giving a fileInput where user can input an excel sheet like this: 'enter image description here'. I have designed an app which looks like this: 'enter image description here'. My code is this:
library(shiny)
library(readxl)
library(tidyverse)
ui <- fluidPage(
fileInput("config","Load Configuration File",accept =c('.xls',',xlsx')),
actionButton("show_fields","Show Fields"),
actionButton("estimate","Estimate"),
uiOutput("ui"),
textOutput("prod")
)
server <- function(input,output) {
x <- reactive({read_excel(input$config$datapath)})
conf <- reactive({x() %>% column_to_rownames(., var = "Rows")})
design <- eventReactive(input$show_fields, {
fluidPage(
numericInput("size","Size",value = 0),
lapply(1:nrow(conf()),function(i) {
selectInput(row.names(conf())[i],label = row.names(conf())[i],choices = colnames(conf()))
})
)
})
output$ui <- renderUI({design()})
mul <- eventReactive(input$estimate, {
sapply(1:nrow(conf()), function(j) {
conf()[row.names(conf())[j],eval(parse(text = paste0("input$",row.names(conf())[j],sep = "")))]
})
})
output$prod <- renderText({paste("Product is: ",prod(mul(),na.rm = TRUE)*input$size)})
}
shinyApp(ui=ui,server = server)
when loading the xls sheet, 'Show Fields' button will show all the Rows as Drop-downs with columns as choices. So at last whatever I choose upon clicking 'Estimate' button Product will be shown of all corresponding values from excel sheet and the inputed size.
So now what I want:
1: All the boxes (numericInput & selectInputs) shall come in two or three columns. The page shall look filled.
2: The actual excel sheet I do have is not exactly I have shown above. It is actually like one you can see in the following image: 'enter image description here'.
Here A-E,U-Z,K-O are drop-downs choices, for corresponding rows(like A-Z for Ram, Shyam etc. , U-Z for Predeep, Sudeep and K-O for Aneeta). I want each such dropdowns and whatever user selects I need to provide the product of all corresponding values from excel sheet along with given Size.
I am trying this out for many days now, and now I am frustated. Somebody please do it.

Related

How to integrate code into a shiny app and upload files?

I'm new to shiny and I would like your advice on a requirement that I have at my office. I apologize in advance for not providing more information or code at the moment.
I have currently coded a R script that does the following:
Import 7 excel files with read_excel:
File 1 will go to dataset 1
File 2 will go to dataset 2
File 3,4,5,6,7 will go to dataset 3 by using lapply
Does a whole lot of data cleaning, formatting, parsing and ordering
Merges everything together and creates a final excel and txt files with specific formatting
Im requiring a shiny web app that:
Provides 3 different upload boxes for the user. One for each type of file (1 / 2 / 3,4,5,6,7)
Internally saves the uploaded files so the code i already have can use them for its processing
Lets the user download the 2 output files made by my code to the computer
If possible, show a log window on the app so the user can know if something goes wrong with the code execution
Datasets visualization is not required
I might be asking a lot. I will appreciate if you just can give me some lights in how i can start working on this. I would like not to modify my current code, if possible (can i have shiny acquire the files, and call my code so it can process them?)
Here is a minimal example showing uploading files, processing them, and downloading them.
For simplicity I've used 3 inputs and a single output.
If you want to notify a user that something has happened, you can use showNotification()
library(shiny)
ui <- fluidPage(
#File Upload Boxes
fileInput("myfileinput_1", label = "Upload File 1", accept = ".csv"),
fileInput("myfileinput_2", label = "Upload File 2", accept = ".csv"),
fileInput("myfileinput_3", label = "Upload File 3", accept = ".csv"),
#Button
actionButton("mybutton", label = "Process Uploaded Files"),
#Table Showing Processed Data
tableOutput("mytable"),
#Download Buttons
downloadButton("myfiledownload", label = "Download Processed File")
)
server <- function(input, output, session) {
#A reactive dataframe to store our outputfile
reactives <- reactiveValues(
df_output = NULL
)
#Runs when button is pressed
observeEvent(input$mybutton, {
#Check that all 3 files are selected before loading
if(!is.null(input$myfileinput_1) & !is.null(input$myfileinput_2) & !is.null(input$myfileinput_3)) {
#Load input files
df_input_1 <- read.csv(input$myfileinput_1$datapath)
df_input_2 <- read.csv(input$myfileinput_2$datapath)
df_input_3 <- read.csv(input$myfileinput_3$datapath)
#Use input to create an output (we're just using a simple example)
reactives$df_output <- data.frame(
input = c("Input 1", "Input 2", "Input 3"),
rows = c(nrow(df_input_1), nrow(df_input_2), nrow(df_input_3))
)
showNotification("Files Successfully Processed", type = "message")
} else {
showNotification("Ensure all three files are selected before loading", type = "error")
}
})
#Table Output
output$mytable <- renderTable({
reactives$df_output
})
#Download handler
output$myfiledownload <- downloadHandler(
filename = "mydata.csv",
content = function(file) {write.csv(reactives$df_output, file, row.names = FALSE)}
)
}
shinyApp(ui, server)

Is there a simple way to generate a section of UI from an uploaded dataset?

I am setting up a shiny application that asks for a dataset, asks for information about said data set, and then runs a series of analytic models on said data set, taking into account information about the dataset (for example, the names of variables to adjust for in a regression). The app starts with a simple UI with a data upload input. Once the user has uploaded their data, I would like the UI to dynamically add a new section that asks the user to select a subset of variables from the column labels of their dataset.
I am working with RStudio Server via a Linux AWS machine.
My app is generated as an add-on to another R package that serves as a wrapper for most of the statistical functions I require. Since the app is quite large, the UI is composed of some standard text and a series of functions that call tabItems for the UI.
In the example below, the UI has a standard data upload user input. In addition to this I have attempted to use shiny::renderUI on the server side to take the user-provided dataset, read the columns, and return the set of columns via shiny::varSelectInput(). Unfortunately, my app does not provide this new input after uploading the data.
ui_data_1 <- function(){
y<-tabItem(tabName = "load_dat",
shiny::tabsetPanel(type = "tabs",
# Data upload ---- -
h2("Data"),
p("Please upload your data file"),
shiny::fileInput(
inputId = "data_file", label = "Upload patient data file (.csv Only)",
accept = c(".csv")
),
h2("Treatment"),
p("Instructions for treatment"),
shiny::uiOutput("variables"))
)
)
return(y)
}
server_data_1 <- function(){
y <- shiny::renderUI({
inFile <- input$data_file
# Load data
if (is.null(inFile)) {
df <- shiny::reactive({NULL})
} else {
df <- shiny::reactive({read.csv(inFile$datapath, header = input$header)})
}
varnames <- colnames(df())
shiny::varSelectInput(
inputId = "treat",
label = "Treatment Variable",
data = c(varnames)
)
})
return(y)
}
#UI.R
body <- shinydashboard::dashboardBody(
ui_data_1()
)
ui <- shinydashboard::dashboardPage(header, sidebar, body, skin = "black")
#Server.R
server <- function(input, output) {
output$variables <- server_data_1()
}
shiny::shinyApp(ui, server)
The app loads properly, as does the data upload menu. When I upload the data, I receive a notification indicating that the upload was successful. The label associated with inputId = "treat" is visible the entire time. However, the variable selection menu does not populate after uploading the data as expected. Perhaps I've done something wrong. Thanks in advance for any advice.

Write.csv using Action buttons

So basically I am trying to make a small setup of sorts and once a certain analysis is done, I would want to export a certain dataset generated to a predefined location and a predefined name (based on the inputs selected earlier). For this purpose, I used the action button which when clicked does this,
observeEvent(input$export_button, {
write.csv(input_dummy_data4ads,paste0("Dummy Files/",unique(input_dummy_data4ads$Dependent_Variable),"_", unique(input_dummy_data4ads$Model_Type),"_", unique(input_dummy_data4ads$AGM),".csv"),row.names = F,na="")
})
The issue here is that if I click the action button once, it generates the desired csv file and at the desired location too. But after pressing it once, it takes the value of 1 (input$export_button) so when I select a new set of inputs using the radio buttons and generate a new plot based on that (by clicking another action button), the app saves a new csv file with a new name (based on the new inputs) at the desired location. What I am trying to do is to reset the value of the action button so that the new csv file is created only when I click it every time.
I tried to understand this but could not incorporate it https://github.com/rstudio/shiny/issues/167
There are specific functions in shiny for this, use downloadButton in your ui and downloadHandler in server.
server.R:
output$export_data <- downloadHandler(
filename = function() {
paste0("Dummy Files/", unique(input_dummy_data4ads$Dependent_Variable), "_", unique(input_dummy_data4ads$Model_Type), "_", unique(input_dummy_data4ads$AGM), ".csv")
},
content = function(con) {
write.csv(input_dummy_data4ads, con, row.names = F, na = "")
}
)
ui.R:
downloadButton("export_data", "Export")

Displaying output in shiny main panel of the shiny UI (code is running without any error still result is not displayed on the UI)

I am trying to create a UI on which I can upload a file and also there is a text input where I can write the product name which I want to search in the uploaded file. I am doing that using the Levenshtein Distance function (adist() function). Now, once i get the results for which the edit distance is 0, I want to display those rows in the Table on the Main Panel. Whatever input is given in the Text input on the UI is searched against the items column in the file uploaded. A sample image of the CSV file which is uploaded is this-
Sample image of the CSV file which is input by the user
Once I run the code and find the edit distance for all the words, I store them in a vector and then use this to print the rows from the file which have edit distance equal to 0. The problem is that when I click on submit, the result is not displayed on the UI but it is displayed on the R-studio console. How do I fix this?
Please help me with the code.
library(shiny)
ui = shinyUI(fluidPage(
titlePanel("LEVENSHTEIN DISTANCE function trial"),
sidebarLayout(
sidebarPanel(
numericInput("rows","Enter the number of rows",value=NULL),
textInput("product", "input product name"),
br(),
br(),
fileInput("file", "Input the file"),
submitButton("Find!")),
mainPanel(
tableOutput("result")
)
)
))
server = shinyServer(function(input,output) {
output$result <- renderPrint({ if (is.null(input$file)) return( );
trial = read.csv(input$file$datapath)
ls = vector('list', length = input$rows)
for(i in 1:input$rows) {
edit = adist("earbuds", trial$items[i])
new_edit = as.numeric(edit)
ls[i] = edit
if(ls[i]==0) print(trial[i, ])
}
})
})
shinyApp(ui=ui,server=server)
Thank You!
It is very hard to provide working code without sample input date. But, here is my attempt at giving you what I think should work.
server = shinyServer(function(input,output) {
output$result <- renderTable({
if (!is.null(input$file)) {
trial = read.csv(input$file)
trial <- trial[adist('earbuds', trial$items) == 0), ]
}
})
})
If you provide input data and expected output table, I can edit the answer to be more precise.

DataTable TableTools Extension Implementation in Shiny

I've got a dataTabe for which I'm trying to implement tableTools in order to export the records in csv format. However, when the filtered data is more than 1 page worth of records, as in the example provided here, the export button doesn't pick up the records on the 2nd page and onwards and it only exports the 1st page.
From my research, it appears that oSelectorOps:{ page: 'all' } option should do the trick. However I couldn't get it to work. If you run the code below and hit the export button, it will result in a csv file with only 100 rows (i.e. the first page) and not the entire table. Please advise if my syntax is incorrect or if there's a better alternative to attain this.
Please note that I don't want to use the downloadHandler because I would like to be able to export the data when filtered using the DataTable filter fields, at the bottom of the table.
Please click here and here to help with similar questions.
Here's my reproducible example:
#Load required packages
require(shiny)
#Create a dataframe
df <- data.frame(random=1:160)
server <- function(input,output,session){
#Display df using DataTable and apply desired options
output$display <- renderDataTable({df},
option=list(pageLength=100,
"dom" = 'T<"clear">lfrtip',
"tableTools" = list(
"sSwfPath" = "//cdn.datatables.net/tabletools/2.2.3/swf/copy_csv_xls_pdf.swf",
"aButtons" = list(list("sExtends" = "csv","oSelectorOpts"=list("page"="all"),"sButtonText" = "Export","aButtons" ="csv")))
)
)
}
ui <- shinyUI(fluidPage(
#Add a title
h1('Testing TableTools'),
#Add required JS libraries
tagList(
singleton(tags$head(tags$script(src='//cdn.datatables.net/1.10.4/js/jquery.dataTables.min.js',type='text/javascript'))),
singleton(tags$head(tags$script(src='//cdn.datatables.net/tabletools/2.2.3/js/dataTables.tableTools.min.js',type='text/javascript'))),
singleton(tags$head(tags$link(href='//cdn.datatables.net/tabletools/2.2.3/css/dataTables.tableTools.css',rel='stylesheet',type='text/css')))
),
mainPanel(
#Display results
dataTableOutput('display')
)
))
shinyApp(ui = ui, server = server)
Try this out:
{
sExtends: "csv",
"oSelectorOpts": {
page: 'all',
filter:'applied'
},
"mColumns": "visible"
},

Resources