How to create Shiny R dynamic renderTable, with a number of tables determined by the uploaded CSV files?
A solution is to put everything inside an observe
.
library(shiny)
ui <- fluidPage(
fluidRow(column(3,
wellPanel(
fileInput(
inputId = "files",
label = "Choose cvs files",
accept = c('text/csv',
'text/comma-separated-values,text/plain',
'.csv'),
multiple = TRUE
)
)),
column(5, offset = 1, uiOutput("tables"))))
server <- function(input, output) {
observe({
if (!is.null(input$files)) {
max_table = length(input$files[, 1])
lst <- list()
for (i in 1:length(input$files[, 1])) {
lst[[i]] <-
read.csv(
input$files[[i, 'datapath']],
sep = ",",
header = TRUE,
skip = 4,
dec = "."
)
}
output$tables <- renderUI({
plot_output_list <- lapply(1:max_table, function(i) {
tablename <- paste("tablename", i, sep = "")
tableOutput(tablename)
})
do.call(tagList, plot_output_list)
})
for (i in 1:max_table) {
local({
my_i <- i
tablename <- paste("tablename", my_i, sep = "")
output[[tablename]] <- renderTable({
lst[[my_i]]
})
})
}
}
})
}
shinyApp(ui = ui, server = server)
How to upload multiple tables and display them separately in r shiny?
Here is an example that may be helpful:
https://stackoverflow.com/a/35943224/3460670
Edit: Try this for your server for creating N tables. You can read in your N data files in a list, and dynamically create outputs for the N tables in an observe
expression.
server <- function(input, output) {
observe({
if (!is.null(input$calfile)) {
N_tables = length(input$calfile[, 1])
upload <- list()
for (i in 1:N_tables) {
upload[[i]] <- read.csv(input$calfile$datapath[i])
}
output$contents <- renderUI({
table_output_list <- lapply(1:N_tables, function(i) {
tableOutput(paste0("table_name", i))
})
do.call(tagList, table_output_list)
})
for (i in 1:N_tables) {
local({
my_i <- i
output[[paste0("table_name", my_i)]] <- renderTable({
upload[[my_i]]
})
})
}
}
})
}
Dynamically Creating Images And Tables From User Input In R Shiny
I would approach this by wrapping essentially all of what you're doing in an observeEvent function. I don't think reactive are the natural way to try to get your functions to run since they're more about returning an R object output that runs when required.
Something like:
observeEvent(input$dis,
{
Snapshot <- CreateSnapshot(input$dis)
VisualizationTable <- ProduceTable(input$dis)
fileData <- your read function of choice since it no longer needs to be reactive
output$fileData <- renderTable({
fileData
})
etc..
}
)
So every time the user chooses a discipline the entire thing will run, generating the outputs you want.
If there's no reason you want to produce a csv you could streamline this more by not saving the csv since you save it only to read the file to load it.
R+Shiny: read file and use its content
This code loads the file straight into the output table and doesn't really store the raw table anywhere. This snippet of code is actually loading the file:
df <- read.csv(input$file1$datapath,
header = input$header,
sep = input$sep,
quote = input$quote)
You can use this outside of the renderTable({}) to load the file just as a normal variable and do whatever you want with it.
However, if you set this code straight into the server function, it won't work - since this is a user input, you should set this variable as reactive, so I would do something like this:
df = reactive({
req(input$file1)
df <- read.csv(input$file1$datapath,
header = input$header,
sep = input$sep,
quote = input$quote)
return(df)
})
Then you can call df() and do whatever you want with it. Ofc it would be nice to add try statements or some checks to make sure the file can be loaded properly, like the in the renderTable({}).
So the server side should look like this:
server <- function(input, output) {
df = reactive({
req(input$file1)
df <- read.csv(input$file1$datapath,
header = input$header,
sep = input$sep,
quote = input$quote)
return(df)
})
output$contents <- renderTable({
# input$file1 will be NULL initially. After the user selects
# and uploads a file, head of that data file by default,
# or all rows if selected, will be shown.
req(input$file1)
# when reading semicolon separated files,
# having a comma separator causes `read.csv` to error
tryCatch(
{
df <- read.csv(input$file1$datapath,
header = input$header,
sep = input$sep,
quote = input$quote)
},
error = function(e) {
# return a safeError if a parsing error occurs
stop(safeError(e))
}
)
if(input$disp == "head") {
return(head(df))
}
else {
return(df)
}
})
}
How to track the net number of action button clicks in order to correctly label a series of rendered tables with their count?
We need another obersver to modify the colnames in uiTbl1
. Please check the following:
library(shiny)
library(rhandsontable)
data1 <- data.frame(row.names = c("A","B","C","Sum"),"Col 1"=c(1,1,0,2),check.names=FALSE)
ui <- fluidPage(
br(),
actionButton("addTbl","Add table"),
br(),br(),
tags$div(id = "placeholder",
tags$div(
style = "display: inline-block",
rHandsontableOutput("hottable1")
)
)
)
server <- function(input, output, session) {
uiTbl <- reactiveValues(div_01_tbl = data1)
rv <- reactiveValues()
observeEvent(input$hottable1, {uiTbl$div_01_tbl <- hot_to_r(input$hottable1)})
output$hottable1 <- renderRHandsontable({rhandsontable(uiTbl$div_01_tbl, useTypes = TRUE)})
observeEvent(input$addTbl, {
# divID <- gsub("\\.", "", format(Sys.time(), "%H%M%OS3")) # system time at add used as table ID
divID <- paste0("div_", sprintf("%02d", input$addTbl+1))
dtID <- paste0(divID, "_DT")
btnID <- paste0(divID, "_rmv")
uiTbl[[paste0(divID,"_tbl")]] <- data1 # captures initial dataframe values
insertUI(
selector = "#placeholder",
ui = tags$div(
id = divID,
style = "display:inline-block;",
rHandsontableOutput(dtID),
actionButton(btnID, "Delete", class = "pull-left btn btn-danger"),
)
)
output[[dtID]] <- renderRHandsontable({
req(uiTbl[[paste0(divID,"_tbl")]])
rhandsontable(uiTbl[[paste0(divID,"_tbl")]], useTypes = TRUE)
})
observeEvent(input[[dtID]], {uiTbl[[paste0(divID,"_tbl")]] <- hot_to_r(input[[dtID]])})
observeEvent(input[[btnID]],{
removeUI(selector = paste0("#", divID))
rv[[divID]] <- NULL
uiTbl[[paste0(divID,"_tbl")]] <- NULL
},
ignoreInit = TRUE,
once = TRUE
)
})
observe({
tables_list <- reactiveValuesToList(uiTbl)
tables_list <- tables_list[order(names(tables_list))]
table_lengths <- lengths(tables_list)
cumsum_table_lengths <- cumsum(table_lengths)[table_lengths != 0L]
for(i in seq_along(cumsum_table_lengths)){
names(uiTbl[[names(cumsum_table_lengths[i])]]) <- paste("Col", cumsum_table_lengths[i])
}
})
}
shinyApp(ui, server)
Shiny R renderPlots on the fly
If anyone's still interested in an answer, try this:
library(shiny)
runApp(shinyApp(
ui = shinyUI(
fluidPage(
numericInput("number", label = NULL, value = 1, step = 1, min = 1),
uiOutput("plots")
)
),
server = function(input, output) {
### This is the function to break the whole data into different blocks for each page
plotInput <- reactive({
n_plot <- input$number
total_data <- lapply(1:n_plot, function(i){rnorm(500)})
return (list("n_plot"=n_plot, "total_data"=total_data))
})
##### Create divs######
output$plots <- renderUI({
plot_output_list <- lapply(1:plotInput()$n_plot, function(i) {
plotname <- paste("plot", i, sep="")
plotOutput(plotname, height = 280, width = 250)
})
do.call(tagList, plot_output_list)
})
observe({
lapply(1:plotInput()$n_plot, function(i){
output[[paste("plot", i, sep="") ]] <- renderPlot({
hist(plotInput()$total_data[[i]], main = paste("Histogram Nr", i))
})
})
})
}
))
Related Topics
Shiny Slider Customized Values
How to Predict Survival Probabilities in R
Aws Dynamodb Support for "R" Programming Language
Debugging Package::Function() Although Lazy Evaluation Is Used
Extract Only Folder Name Right Before Filename from Full Path
Plot The Intensity of a Continuous with Geom_Tile in Ggplot
How to Extract Coefficients' Standard Error from an "Aov" Model
Plot Weighted Frequency Matrix
Merge Data Based on Nearest Date R
How to Keep The Only Intersection of The Spatial Features & Remove Everything Outside of a Boundary
How to Create Dynamic Number of Observeevent in Shiny
Netlogo - Misalignment with Imported Gis Shapefiles
Cannot Install R Tseries, Quadprog ,Xts Packages in Linux