What I achieved so far: I have a fully reproducible shiny app (using iris dataset) which makes dynamic plots (one does not know how many plots will output) based on one or more selected dropdown value(s) (Species in this case).
My question: I'd like to add a dynamic subtitle from a column called new. To elaborate, each Species has exactly two unique values (e.g., a and b for Species = setosa). Is there a way to add these unique values so that it could be integrated into the dynamic plots ?
What I tried:
df() %>% select(new) %>% distinct() %>% pull()
However, this does not produce the output I want.
library(shiny)
library(shinydashboard)
library(shinyWidgets)
library(tidyverse)
species <- c("setosa", "versicolor", "virginica")
iris %>% filter(Species == "setosa")
vals1 <- rep(c("a", "b"), 25)
vals2 <- rep(c("c", "d"), 25)
vals3 <- rep(c("e", "f"), 25)
vals <- c(vals1, vals2, vals3)
iris <- iris %>%
mutate(new = vals)
ui <- dashboardPage(
dashboardHeader(title = "title"),
sidebar <- dashboardSidebar(
sidebarMenu(
menuItem("General Overview", tabName = "tab1", icon = icon("dashboard"))
)
),
body <- dashboardBody(
tabItems(
tabItem(
tabName = "tab1",
uiOutput("species_dropdown"),
DT::dataTableOutput("table1"),
textOutput("text1"),
uiOutput("plots")
)
)
)
)
server <- function(input, output) {
output$species_dropdown <- renderUI({
pickerInput(
"var1",
"Species:",
choices = species,
options = pickerOptions(
actionsBox = T,
header = "Close",
liveSearch = T
),
multiple = T
)
})
filtered_data <- reactive({
map(input$var1, ~ iris %>% filter(Species == .x)) %>% set_names(input$var1)
})
output$plots <- renderUI({
req(input$var1)
plot_output_list <- lapply(input$var1, function(i) {
plotname <- paste("plot_", i, sep = "")
plotOutput(plotname, height = 280, width = 250)
})
do.call(flowLayout, plot_output_list)
})
observeEvent(filtered_data(), {
iwalk(filtered_data(), ~ {
output[[paste0("plot_", .y)]] <<- renderPlot({
ggplot(.x, aes(x = Sepal.Length, y = Sepal.Width)) +
geom_point() +
labs(title = .y, x = "Sepal Length", y = "Sepal Width") # how to make and integrate dynamic subtitles from output$text1 ?
})
})
})
df <- reactive({
req(input$var1)
iris %>%
filter(Species == input$var1)
})
output$table1 <- DT::renderDataTable({
df()
})
output$text1 <- renderText({
df() %>% select(new) %>% distinct() %>% pull()
})
}
shinyApp(ui, server)
We can use the information provided by filtered_data and inside the walk function, create during each iteration a variable called subt that will capture the unique values from new column.
observeEvent(filtered_data(), {
iwalk(filtered_data(), ~ {
subt <- pull(., new) %>%
unique() %>%
str_c(collapse = ",")
subt <- paste("Unique values are:", subt)
output[[paste0("plot_", .y)]] <<- renderPlot({
ggplot(.x, aes(x = Sepal.Length, y = Sepal.Width)) +
geom_point() +
labs(title = .y, subtitle = subt, x = "Sepal Length", y = "Sepal Width") # how to make and integrate dynamic subtitles from output$text1 ?
})
})
})
Full app:
library(shiny)
library(shinydashboard)
library(shinyWidgets)
library(tidyverse)
species <- c("setosa", "versicolor", "virginica")
iris %>% filter(Species == "setosa")
vals1 <- rep(c("a", "b"), 25)
vals2 <- rep(c("c", "d"), 25)
vals3 <- rep(c("e", "f"), 25)
vals <- c(vals1, vals2, vals3)
iris <- iris %>%
mutate(new = vals)
ui <- dashboardPage(
dashboardHeader(title = "title"),
sidebar <- dashboardSidebar(
sidebarMenu(
menuItem("General Overview", tabName = "tab1", icon = icon("dashboard"))
)
),
body <- dashboardBody(
tabItems(
tabItem(
tabName = "tab1",
uiOutput("species_dropdown"),
DT::dataTableOutput("table1"),
textOutput("text1"),
uiOutput("plots")
)
)
)
)
server <- function(input, output) {
output$species_dropdown <- renderUI({
pickerInput(
"var1",
"Species:",
choices = species,
options = pickerOptions(
actionsBox = T,
header = "Close",
liveSearch = T
),
multiple = T
)
})
filtered_data <- reactive({
map(input$var1, ~ iris %>% filter(Species == .x)) %>% set_names(input$var1)
})
output$plots <- renderUI({
req(input$var1)
plot_output_list <- lapply(input$var1, function(i) {
plotname <- paste("plot_", i, sep = "")
plotOutput(plotname, height = 280, width = 250)
})
do.call(flowLayout, plot_output_list)
})
observeEvent(filtered_data(), {
iwalk(filtered_data(), ~ {
subt <- pull(., new) %>%
unique() %>%
str_c(collapse = ",")
subt <- paste("Unique values are:", subt)
output[[paste0("plot_", .y)]] <<- renderPlot({
ggplot(.x, aes(x = Sepal.Length, y = Sepal.Width)) +
geom_point() +
labs(title = .y, subtitle = subt, x = "Sepal Length", y = "Sepal Width") # how to make and integrate dynamic subtitles from output$text1 ?
})
})
})
df <- reactive({
req(input$var1)
iris %>%
filter(Species == input$var1)
})
output$table1 <- DT::renderDataTable({
df()
})
output$text1 <- renderText({
df() %>%
select(new) %>%
unique() %>%
pull()
})
}
shinyApp(ui, server)
Related
The dashboard below has two tabs. Data is refreshed on changing the parameter. The first tab is refreshing properly with change in parameter. The second tab is not refreshed even though the parameter is used with reactive function. The code is very basic with the minimum functionality for testing and demo
The problem is of interaction hence these components are required. Also if you see..from following perspective. 1) data portion will setup the problem 2) 2 tabs are created to show the issue 3) tabs has minimum data displayed to show the failure of refresh...I can say this as I have removed the portion of code which was not directly linked with the problem.
library(quantmod)
library(shiny)
library(dplyr)
library(purrr)
library(stringr)
get_data <- function(symbols = c("AAPL", "MSFT", "META", "ORCL",
"TSLA", "GOOG")) {
syms <- getSymbols(symbols, from = "2020/01/01",
to = Sys.Date(), periodicity = "daily")
map_dfr(syms, function(sym) {
raw_data <- get(sym)
raw_data %>%
as_tibble() %>% # as_tibble will convert to tibble
set_names(c("OPEN", "HIGH", "LOW", "CLOSE", "VOLUME", "ADJUSTED")) %>%
mutate(SYMBOL = sym,
DATE = index(raw_data)) %>%
select(SYMBOL, DATE, OPEN, HIGH, LOW, CLOSE, VOLUME, ADJUSTED)
})}
if (!exists("df_all")) {df_all <- get_data()}
df_rep_data <- tribble(~ RunDate, ~ ListStocks,
"2020-01-06", "AAPL, GOOG, TSLA",
"2021-01-04", "ORCL",
"2022-01-04", "META, MSFT") %>%
mutate(RunDate = as.Date(RunDate))
make_table <- function(symbol, dat = df_all) {
dat %>%
filter(SYMBOL == symbol) %>%
select(DATE, OPEN, HIGH, LOW, CLOSE, VOLUME) %>%
slice(1:5)}
symb_ui <- function(id) {
ns <- NS(id)
tagList(
tags$h4(textOutput(ns("symbol"))),
tableOutput(ns("table"))
)}
symb_server <- function(id, get_symbol_name) {
moduleServer(id, function(input, output, session) {
ns <- session$ns
output$symbol <- renderText(get_symbol_name())
output$table <- renderTable(make_table(get_symbol_name()))
})}
OneStock_ui <- function(id) {
ns <- NS(id)
tagList(
tags$h4(textOutput(ns("OneStocksymbol"))),
tableOutput(ns("OneStocktable"))
)}
OneStock_server <- function(id, get_symbol_date) {
moduleServer(id, function(input, output, session) {
ns <- session$ns
output$OneStocksymbol <- renderText(get_symbol_date())
output$OneStocktable <- renderTable(make_table(get_symbol_date()))
})}
ui <- fluidPage(
tabsetPanel(
tabPanel(
selectInput("run_date", "Run Date", df_rep_data %>% pull(RunDate)),
tags$h2(textOutput("date_output")),
tags$h3(textOutput("lst_symb_output")),
uiOutput("symbols_output")),
tabPanel(
textInput("OneStockChart_input",'OneStockAnalysis', value = 'MSFT'),
uiOutput("OneStockAnalysis_output"))
))
server <- function(input, output, session) {
handler <- list()
get_syms <- list()
get_syms_onestock <- list()
handler_onestock <- list()
output$date_output <- renderText(req(input$run_date))
output$lst_symb_output <- renderText({
df_rep_data %>%
filter(RunDate == req(input$run_date)) %>%
pull(ListStocks)
})
output$symbols_output <- renderUI({
symbols <- df_rep_data %>%
filter(RunDate == req(input$run_date)) %>%
pull(ListStocks) %>%
str_split(fixed(", ")) %>%
unlist()
syms <- vector("list", length(symbols)) %>%
set_names(symbols)
for (sym in symbols) {
local({
my_sym <- sym
syms[[my_sym]] <<- symb_ui(my_sym)
get_syms[[my_sym]] <<- reactive(my_sym)
handler[[my_sym]] <<- symb_server(my_sym, get_syms[[my_sym]])
})
}
tagList(syms)
})
output$OneStockAnalysis_output <- renderUI({
symbols_onestock <- list(req(input$OneStockChart_input)) %>%
unlist()
syms_onestock <- vector("list", length(symbols_onestock)) %>%
set_names(symbols_onestock)
for (sym_onestock in symbols_onestock) {
local({
my_sym_onestock <- sym_onestock
syms_onestock[[my_sym_onestock]] <<- symb_ui(my_sym_onestock)
get_syms_onestock[[my_sym_onestock]] <<- reactive(my_sym_onestock)
handler_onestock[[my_sym_onestock]] <<- symb_server(my_sym_onestock, get_syms_onestock[[my_sym_onestock]])
})
}
tagList(syms_onestock)
})}
shinyApp(ui = ui, server = server)
I'm trying to make a simple Shiny dashboard using the iris dataset in R.
What I accomplished so far: The current dashboard has two dropdowns. One that filters the Species column and one for the subspecies column that's dependent on the first dropdown. These two dropdowns work.
What's not working: Based on the two dropdowns, I'd like to see a datatable which should be a filtered dataset.
I think I'm using a wrong name space ?
Any advice would be of great help!
library(shiny)
library(DT)
library(dplyr)
## global.R
# Create sub_species column
iris2 <- iris %>%
mutate(
subspecies = case_when(
startsWith(as.character(Species), "setosa") ~ rep(c("setosa1", "setosa2"), length.out = n()),
startsWith(as.character(Species), "versicolor") ~ rep(c("versicolor1", "versicolor2"), length.out = n()),
startsWith(as.character(Species), "virginica") ~ rep(c("virginica1", "virginica2"), length.out = n())
)
)
## ui.R
fluidPage(
sidebarLayout(
sidebarPanel(
dropdownsUI("dropdowns")
),
mainPanel(
DT::dataTableOutput("table1")
)
)
)
## server.R
function(input, output, session) {
subspeciesServer("dropdowns")
data1 <- filteredDataServer("table1")
output$table1 <- DT::renderDataTable({
data1()
})
}
## modules.R
# UI logic
dropdownsUI <- function(id) {
ns <- NS(id)
# All input IDs in the function body must be wrapped with ns()
tagList(
selectInput(ns("speciesDropdown"), label = "Species:", choices = c("setosa", "versicolor", "virginica")),
uiOutput(ns("subspeciesDropdown")),
DT::dataTableOutput(ns("datatable"))
)
}
# Sub Species Dropdown logic
subspeciesServer <- function(id) {
moduleServer(id, function(input, output, session) {
dependent_subspecies <- reactive({
iris2 %>%
filter(Species == req(input$speciesDropdown)) %>%
pull(subspecies) %>%
unique()
})
output$subspeciesDropdown <- renderUI({
selectInput("vars_subspecies", "Sub Species:", choices = dependent_subspecies())
})
}
)
}
# Filtered data logic
filteredDataServer <- function(id) {
moduleServer(id, function(input, output, session) {
df <- reactive({
req(input$speciesDropdown, input$subspeciesDropdown)
iris2 %>%
# may be this what's causing the error ?
filter(Species %in% input$speciesDropdown & subspecies %in% input$vars_subspecies)
})
return(df)
}
)
}
Apart from namespace issue, you had a few other issues. You need to pass the reactive variables between modules. They are not available globally. Try this
library(shiny)
library(DT)
library(dplyr)
## global.R
# Create sub_species column
iris2 <- iris %>%
dplyr::mutate(
subspecies = case_when(
startsWith(as.character(Species), "setosa") ~ rep(c("setosa1", "setosa2"), length.out = n()),
startsWith(as.character(Species), "versicolor") ~ rep(c("versicolor1", "versicolor2"), length.out = n()),
startsWith(as.character(Species), "virginica") ~ rep(c("virginica1", "virginica2"), length.out = n())
)
)
## modules.R
# UI logic
dropdownsUI <- function(id) {
ns <- NS(id)
# All input IDs in the function body must be wrapped with ns()
tagList(
selectInput(ns("speciesDropdown"), label = "Species:", choices = c("setosa", "versicolor", "virginica")),
uiOutput(ns("subspeciesDropdown"))
#,DT::dataTableOutput(ns("datatable"))
)
}
# Sub Species Dropdown logic
subspeciesServer <- function(id) {
moduleServer(id, function(input, output, session) {
ns <- session$ns
rv <- reactiveValues()
dependent_subspecies <- reactive({
iris2 %>%
filter(Species == req(input$speciesDropdown)) %>%
pull(subspecies) %>%
unique()
})
output$subspeciesDropdown <- renderUI({
req(dependent_subspecies())
selectInput(ns("vars_subspecies"), "Sub Species:", choices = dependent_subspecies())
})
observe({
rv$var1 <- input$speciesDropdown
rv$var2 <- input$vars_subspecies
})
return(rv)
}
)
}
# Filtered data logic
filteredDataServer <- function(id,sp,subsp,mydf) {
moduleServer(id, function(input, output, session) {
df <- reactive({
mydf %>% dplyr::filter(subspecies %in% subsp())
})
return(df)
}
)
}
## ui.R
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
dropdownsUI("dropdowns")
),
mainPanel(
DT::dataTableOutput("table1")
)
)
)
## server.R
server <- function(input, output, session) {
myvars <- subspeciesServer("dropdowns")
data1 <- filteredDataServer("table1", reactive(myvars$var1), reactive(myvars$var2),iris2)
output$table1 <- DT::renderDataTable({
datatable(req(data1()))
})
}
shinyApp(ui = ui, server = server)
This question is related to one I asked here: Dynamic Plots Based on One or More Dropdown Values. Although I got an answer from Mr.Rlover, the resulting plots do not look the same. If I choose two or more plots, it seems that the data is being added on and this is reflected exactly in the plots. I wonder how one would separate data based on different species.
one species selected
two or more species selected
Below was my original question:
I am trying to make multiple dynamic plots (one does not know how many plots will output) based on one or more selected dropdown value(s) (species in this case).
I did succeed making plots based on the dropdown. For instance, two plots are displayed if a user selected two values/species from the dropdown list, one plot is displayed if one value/species is selected.
Although the number of plots match the number of dropdown values, the plots show a duplicate if two or more dropdown values/species are selected (it only works if exactly one value is selected). Any advice would be of great help.
The below code uses the iris dataset in R.
library(shiny)
library(shinyWidgets)
library(ggplot2)
library(tidyverse)
library(shinydashboard)
species = c("setosa", "versicolor", "virginica")
ui <- dashboardPage(
dashboardHeader(title = "title"),
sidebar <- dashboardSidebar(
sidebarMenu(
menuItem("General Overview", tabName = "tab1", icon = icon("dashboard"))
)
),
body <- dashboardBody(
tabItems(
tabItem(
tabName = "tab1",
uiOutput("species_dropdown"),
# DT::dataTableOutput("table1"),
uiOutput("plots")
)
)
)
)
server <- function(input, output) {
output$species_dropdown <- renderUI({
pickerInput(
"var1",
"Species:",
choices = species,
options = pickerOptions(
actionsBox = T,
header = "Close",
liveSearch = T
),
multiple = T
)
})
filtered_data <- reactive({
iris %>%
filter(Species %in% input$var1) # I think is causing the problem
})
output$table1 <- DT::renderDataTable({
req(input$var1)
filtered_data()
})
# Insert the right number of plot output objects into the web page
output$plots <- renderUI({
req(input$var1)
plot_output_list <- lapply(1:length(input$var1), function(i) {
plotname <- paste("plot", i, sep="")
plotOutput(plotname, height = 280, width = 250)
})
do.call(tagList, plot_output_list)
})
for (i in 1:length(species)) {
local({
my_i <- i #crucial
plotname <- paste("plot", my_i, sep="") # use my_i instead of i
output[[plotname]] <- renderPlot({
ggplot(filtered_data(), aes(x = Sepal.Length, y = Sepal.Width)) +
geom_point() +
labs(title = paste(input$var1[my_i], sep = ""), x = "Sepal Length", y = "Sepal Width") # title needs input$var1 indexed as paste will return a list otherwise, in which case only a first element gets used for the title hence all titles are identical
})
})
}
}
shinyApp(ui, server)
By doing iris %>% filter(Species %in% input$var1) only one dataset was generated. We need one per number of Species.
Instead we create a list with each corresponding plot:
filtered_data <- reactive({
map(input$var1, ~
iris %>%
filter(Species == .x))
})
and subset it with filtered_data()[[index]]
Full app
library(shiny)
library(shinydashboard)
library(shinyWidgets)
library(tidyverse)
species <- c("setosa", "versicolor", "virginica")
ui <- dashboardPage(
dashboardHeader(title = "title"),
sidebar <- dashboardSidebar(
sidebarMenu(
menuItem("General Overview", tabName = "tab1", icon = icon("dashboard"))
)
),
body <- dashboardBody(
tabItems(
tabItem(
tabName = "tab1",
uiOutput("species_dropdown"),
uiOutput("plots")
)
)
)
)
server <- function(input, output) {
output$species_dropdown <- renderUI({
pickerInput(
"var1",
"Species:",
choices = species,
options = pickerOptions(
actionsBox = T,
header = "Close",
liveSearch = T
),
multiple = T
)
})
filtered_data <- reactive({
map(input$var1, ~
iris %>%
filter(Species == .x)) %>%
set_names(input$var1)
})
#Insert the right number of plot output objects into the web page
output$plots <- renderUI({
req(input$var1)
plot_output_list <- lapply(input$var1, function(i) {
plotname <- paste("plot_", i, sep = "")
plotOutput(plotname, height = 280, width = 250)
})
do.call(tagList, plot_output_list)
})
observeEvent(filtered_data(), {
iwalk(filtered_data(), ~{
output[[paste0("plot_",.y)]] <<- renderPlot({
ggplot(.x, aes(x = Sepal.Length, y = Sepal.Width)) +
geom_point() +
labs(title = .y, x = "Sepal Length", y = "Sepal Width")
})
})
})
}
shinyApp(ui, server)
Using iris %>% filter(Species %in% input$var1[my_i]) directly inside local({}) was the key instead of using:
filtered_data <- reactive({
iris %>%
filter(Species %in% input$var1)
})
for (i in 1:length(species)) {
local({
my_i <- i
plotname <- paste("plot", my_i, sep="")
output[[plotname]] <- renderPlot({
ggplot(iris %>% filter(Species %in% input$var1[my_i]), aes(x = Sepal.Length, y = Sepal.Width)) +
geom_point() +
labs(title = paste(input$var1[my_i], sep = ""), x = "Sepal Length", y = "Sepal Width")
})
})
}
I'm building a shiny app that would display in dygraphs a basic dataset and then offer an option to add new time series upon selecting the checkbox input. However, as I coded it now, I'm 'stuck' at the original dataset and unable to add/remove new content. Any hints how to solve this are very welcome, thanks.
library(shinydashboard)
library(dygraphs)
library(dplyr)
ui <-dashboardPage(
dashboardHeader(),
dashboardSidebar(),
dashboardBody(
useShinyjs(),
checkboxGroupInput(inputId = 'options',
label = 'Choose your plot(s)',
choices = list("mdeaths" = 1,
"ldeaths" = 2)
),
uiOutput("Ui1")
)
)
server <- function(input, output, session) {
output$Ui1 <- renderUI({
output$plot1 <- renderDygraph({
final_ts <- ldeaths
p <- dygraph(final_ts, main = 'Main plot') %>%
dygraphs::dyRangeSelector()
if(1 %in% input$options) {
final_ts <- cbind(final_ts, mdeaths)
p <- p %>%
dySeries('mdeaths', 'Male Deaths')
} else if(2 %in% input$options) {
final_ts <- cbind(final_ts, fdeaths)
p <- p %>%
dySeries('fdeaths', 'Female Deaths')
}
p
})
dygraphOutput('plot1')
})
}
shinyApp(ui, server)
I'd suggest to dynamically filter the data based on the user selection instead of dynamically adding/removing traces from the plot:
library(shinydashboard)
library(shinyjs)
library(dygraphs)
library(dplyr)
lungDeaths <- cbind(ldeaths, mdeaths, fdeaths)
ui <- dashboardPage(
dashboardHeader(),
dashboardSidebar(),
dashboardBody(
useShinyjs(),
selectizeInput(
inputId = "options",
label = "Choose your trace(s)",
choices = colnames(lungDeaths),
selected = colnames(lungDeaths)[1],
multiple = TRUE,
options = list('plugins' = list('remove_button'))
),
uiOutput("Ui1")
)
)
server <- function(input, output, session) {
output$Ui1 <- renderUI({
filteredLungDeaths <- reactive({
lungDeaths[, input$options]
})
output$plot1 <- renderDygraph({
p <- dygraph(filteredLungDeaths(), main = 'Main plot') %>%
dygraphs::dyRangeSelector()
if('mdeaths' %in% colnames(filteredLungDeaths())){
p <- dySeries(p, 'mdeaths', 'Male Deaths')
}
if('fdeaths' %in% colnames(filteredLungDeaths())){
p <- dySeries(p, 'fdeaths', 'Female Deaths')
}
p
})
dygraphOutput('plot1')
})
}
shinyApp(ui, server)
I developed a Shiny application to include couple of plots and data under different tabs.Tabs are created dynamically using another parameter.But each time i have to subset the data to prepare the plots. Say using 'mpg' subsetdata i plotted 2 different types of graphs in 'mpg' tab and i don't want to subset data every time(currently i sub set every time) when i draw the plot.For all calculations in one tab, i would like to subset the data only once.Appreciate some help
write.csv(mtcars,'mtcars.csv')
write.csv(mtcars,'mtcars.csv')
library(shiny)
library(plyr)
library(dplyr)
library(DT)
library(data.table)
ui <- pageWithSidebar(
headerPanel = headerPanel('data'),
sidebarPanel = sidebarPanel(fileInput(
'mtcars', h4('Uplaodmtcardata in csv format')
),
uiOutput('tabnamesui')),
mainPanel(uiOutput("tabsets"))
)
server <- function(input, output, session) {
mtcarsFile <- reactive({
input$mtcars
})
xxmtcars <-
reactive({
read.table(
file = mtcarsFile()$datapath,
sep = ',',
header = T,
stringsAsFactors = T
)
})
tabsnames <- reactive({
names(xxmtcars())
})
output$tabnamesui <- renderUI({
req(mtcarsFile())
selectInput(
'tabnamesui',
h5('Tab names'),
choices = as.list(tabsnames()),
multiple = T
# selected = SalesGlobalDataFilter1Val()
)
})
tabnamesinput <- reactive({
input$tabnamesui
})
output$tabsets <- renderUI({
req(mtcarsFile())
tabs <-
reactive({
lapply(tabnamesinput(), function(x)
tabPanel(title = basename(x)
,fluidRow(splitLayout(cellWidths = c("50%", "50%"),
plotOutput(paste0('plot1',x)),
plotOutput(paste0('plot2',x)
))),fluidRow(splitLayout(cellWidths =
c("50%", "50%"),
plotOutput(paste0('plot3',x)),
plotOutput(paste0('plot4',x)
))),
dataTableOutput(paste0('table',x))))
})
do.call(tabsetPanel, c(tabs()))
})
observe(
lapply(tabnamesinput(), function(x) {
output[[paste0('table',x)]] <-
renderDataTable({as.data.table((select(xxmtcars(),x)))#CODE REPEATED
})}))
observe(
lapply(tabnamesinput(), function(x) {
output[[paste0('plot1',x)]] <-
renderPlot({as.data.table((select(xxmtcars(),x)))%>%plot()#CODE REPEATED
})
})
)
observe(
lapply(tabnamesinput(), function(x) {
output[[paste0('plot2',x)]] <-
renderPlot({as.data.table((select(xxmtcars(),x)))%>%plot()#CODE #REPEATED
})
})
)
observe(
lapply(tabnamesinput(), function(x) {
output[[paste0('plot3',x)]] <-
renderPlot({as.data.table((select(xxmtcars(),x)))%>%plot()#CODE REPEATED
})
})
)
observe(
lapply(tabnamesinput(), function(x) {
output[[paste0('plot4',x)]] <-
renderPlot({as.data.table((select(xxmtcars(),x)))%>%plot()#CODE REPEATED
})
})
)
}
runApp(list(ui = ui, server = server))
You can save your sub data into a reactive object and call it when you need.
library(shiny)
library(plyr)
library(dplyr)
library(DT)
library(data.table)
ui <- pageWithSidebar(
headerPanel = headerPanel('data'),
sidebarPanel = sidebarPanel(fileInput(
'mtcars', h4('Uplaodmtcardata in csv format')
),
uiOutput('tabnamesui')),
mainPanel(uiOutput("tabsets"))
)
server <- function(input, output, session) {
mtcarsFile <- reactive({
input$mtcars
})
xxmtcars <-
reactive({
read.table(
file = mtcarsFile()$datapath,
sep = ',',
header = T,
stringsAsFactors = T
)
})
tabsnames <- reactive({
names(xxmtcars())
})
output$tabnamesui <- renderUI({
req(mtcarsFile())
selectInput(
'tabnamesui',
h5('Tab names'),
choices = as.list(tabsnames()),
multiple = T
# selected = SalesGlobalDataFilter1Val()
)
})
tabnamesinput <- reactive({
input$tabnamesui
})
output$tabsets <- renderUI({
req(mtcarsFile())
tabs <-
reactive({
lapply(tabnamesinput(), function(x)
tabPanel(title = basename(x)
,fluidRow(splitLayout(cellWidths = c("50%", "50%"),
plotOutput(paste0('plot1',x)),
plotOutput(paste0('plot2',x)
))),fluidRow(splitLayout(cellWidths =
c("50%", "50%"),
plotOutput(paste0('plot3',x)),
plotOutput(paste0('plot4',x)
))),
dataTableOutput(paste0('table',x))))
})
do.call(tabsetPanel, c(tabs()))
})
# Save your sub data here
subsetdata<-reactive({
list_of_subdata<-lapply(tabnamesinput(), function(x) {
as.data.table((select(xxmtcars(),x)))
})
names(list_of_subdata)<-tabnamesinput()
return(list_of_subdata)
})
observe(
lapply(tabnamesinput(), function(x) {
output[[paste0('table',x)]] <-
renderDataTable({
subsetdata()[[x]]
})}))
observe(
lapply(tabnamesinput(), function(x) {
for(i in paste0("plot",1:4)){
output[[paste0(i,x)]] <-
renderPlot({subsetdata()[[x]]%>%plot()#CODE REPEATED
})
}
})
)
}
runApp(list(ui = ui, server = server))