I have the shiny dashboard below in which if I give a name except of the default consent.name,then the password makis and press the Get started actionbutton an rmd output is generated. Then the user can press 'Generate report' in order to download this as pdf. Basically what I want to do is to display the 'Generate report' downloadButton() only when the report is created and displayed in the body because otherwise it has no meaning and is confusing. I tried to applied the observeEvent() method which I used for the report creation as well but it does not work and the downloadButton() is always there.
library(shiny)
library(shinydashboard)
library(shinydashboardPlus)
library(shinyjs)
library(knitr)
mytitle <- paste0("Life, Death & Statins")
dbHeader <- dashboardHeaderPlus(
titleWidth = "0px",
tags$li(a(
div(style = "margin-left:-15px;margin-bottom:-83px;margin-top:-15px;padding: 0px 1190px 0px 0px ; width: 290px;",
img(src = 'download.png', height = "125px",width="232px")),
div(style="display: inline;margin-top:-35px; padding: 0px 90px 0px 1250px ;font-size: 58px ;color: black;font-family:Times-New Roman;font-weight: bold; width: 500px;",HTML(mytitle)),
div(style="display: inline;margin-top:25px; padding: 0px 0px 0px 1250px;vertical-align:top; width: 150px;", actionButton("well", "Welcome"))
),
class = "dropdown")
)
shinyApp(
ui = dashboardPagePlus(
header = dbHeader,
sidebar = dashboardSidebar(width = "0px",
sidebarMenu(id = "sidebar", # id important for updateTabItems
menuItem("Welcome", tabName = "well", icon = icon("house"))
) ),
body = dashboardBody(
useShinyjs(),
tags$script(HTML("$('body').addClass('fixed');")),
tags$head(tags$style(".skin-blue .main-header .logo { padding: 0px;}")),
tabItems(
tabItem("well",
fluidRow(),
tags$hr(),
tags$hr(),
fluidRow(
column(5,),
column(6,
fluidRow(column(3,textInput("name", label = ("Name"), value = "consent.name"))),
fluidRow(
column(5,),
column(6,passwordInput("pwd", "Enter the Database browser password")
)),
actionButton("button", "Get started",style='padding:4px; font-size:140%'),
fluidRow(
column(3,
downloadButton("report", "Generate report",style='padding:4px; font-size:180%')
),
column(6,
uiOutput('markdown')
)))))
)
)
),
server<-shinyServer(function(input, output,session) {
hide(selector = "body > div > header > nav > a")
observeEvent(input$button,{
if (input$name=="consent.name"){
return(NULL)
}
else{
if(input$pwd=="makis"){
output$markdown <- renderUI({
HTML(markdown::markdownToHTML(knit('ex.rmd', quiet = TRUE)))
})
}
else{
return(NULL)
}
}
})
observeEvent(input$button,{
if (input$name=="consent.name"){
return(NULL)
}
else{
if(input$pwd=="makis"){
output$report <- downloadHandler(
# For PDF output, change this to "report.pdf"
filename = "report.pdf",
content = function(file) {
tempReport <- file.path(tempdir(), "ex.Rmd")
file.copy("ex.Rmd", tempReport, overwrite = TRUE)
rmarkdown::render(tempReport, output_file = file,
envir = new.env(parent = globalenv())
)
}
)
}
else{
return(NULL)
}
}
})
}
)
)
Using the renderXXX functions inside observers is not recommended.
Here is a way:
library(shiny)
library(markdown)
library(rmarkdown)
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
passwordInput("pwd", "Password"),
conditionalPanel(
condition = "output.passwordOK",
actionButton("button", "Generate report"),
),
conditionalPanel(
condition = "output.reportDone",
downloadButton("dwnld", "Download report")
)
),
mainPanel(
uiOutput("preview")
)
)
)
server <- function(input, output, session){
# indicator report has been generated
reportDone <- reactiveVal(FALSE)
output[["reportDone"]] <- reactive({
reportDone()
})
outputOptions(output, "reportDone", suspendWhenHidden = FALSE)
# indicator password is right
passwordOK <- eventReactive(input[["pwd"]], {
input[["pwd"]] == "darwin"
})
output[["passwordOK"]] <- reactive({
passwordOK()
})
outputOptions(output, "passwordOK", suspendWhenHidden = FALSE)
# generate report preview on button click
HTMLreport <- eventReactive(input[["button"]], {
req(passwordOK())
reportDone(TRUE)
HTML(markdownToHTML("www/ex.Rmd", output = NULL))
})
output[["preview"]] <- renderUI({
HTMLreport()
})
# download handler
output[["dwnld"]] <- downloadHandler(
filename = "report.html",
content = function(file){
render("www/ex.Rmd", output_file = file)
}
)
}
shinyApp(ui, server)
Related
When running the code below, you will notice that I have two options below. If you press the Excel option, a fileInput will appear right below the radioButtons. However, I would like to know if it is possible to separate fileInput from radioButtons. I will insert an image to clarify what I want. See that they are separated.
Executable code below:
library(shiny)
library(dplyr)
library(shinyjs)
library(shinythemes)
library(readxl)
ui <- fluidPage(
shiny::navbarPage(theme = shinytheme("flatly"), collapsible = TRUE,
br(),
tabPanel("PAGE1",
sidebarLayout(
sidebarPanel(
radioButtons("button",
label = h3("Data source"),
choices = list("Excel" = "Excel",
"Database" = "database"),
selected = "File"),
uiOutput('fileInput'),
),
mainPanel(
)))))
server <- function(input, output) {
observe({
if(is.null(input$button)) {
}else if (input$button =="Excel"){
output$fileInput <- renderUI({
fileInput("file",h4("Import file"), multiple = T, accept = ".xlsx")
})
} else if(input$button=="database"){
output$fileInput <- NULL
} else {
output$fileInput <- NULL
}
})
}
shinyApp(ui = ui, server = server)
Example:
I left it in red to specify the space
A possible workaround could be to use fluidRow with two columns to simulating a sidebarPanel with a mainPanel.
Notice that I wrapped the inputs in a div(class = "well well-lg") for the background.
App
library(shiny)
library(dplyr)
library(shinyjs)
library(shinythemes)
library(readxl)
ui <- navbarPage(
theme = shinytheme("flatly"), collapsible = TRUE,
br(),
tabPanel(
"PAGE1",
fluidRow(
column(
width = 6,
fluidRow(div(
class = "well well-lg",
radioButtons("button",
label = h3("Data source"),
choices = list(
"Excel" = "Excel",
"Database" = "database"
),
selected = "File"
)
)),
fluidRow(
uiOutput("fileInput")
)
),
column(
width = 6,
tableOutput("iris")
)
)
)
)
server <- function(input, output) {
output$iris <- renderTable({
iris
})
observe({
if (is.null(input$button)) {
} else if (input$button == "Excel") {
output$fileInput <- renderUI({
div(class = "well well-lg", fileInput("file", h4("Import file"), multiple = T, accept = ".xlsx"))
})
} else if (input$button == "database") {
output$fileInput <- NULL
} else {
output$fileInput <- NULL
}
})
}
shinyApp(ui = ui, server = server)
I have a beginner problem. I need to turn columns into checkbox. Next, I need to assign integer values to these checkbox (1,2,3) so that they are transported to the function "int<-csv()[,c(5,6,7,8,9,10)]" (where the numeric values are separated by commas). Also, I need that if more than one item is selected, a comma is placed to the right of it. It is possible? Thanks in advance!
This is my code:
library(shiny)
library(shinydashboard)
library(shinyWidgets)
library(readxl)
library(tidyverse)
library(readxl)
library(stringr)
# Dashboard
ui <- dashboardPage(
dashboardHeader(
title = "Page"
),
dashboardSidebar(
sidebarMenu(
menuItem(
"Home",
tabName = "home")
)
),
dashboardBody(
tabItems(
# Home
tabItem(
tabName = "home", h2("Hello!"),
br(),
box(
width = 100,
fileInput("file", "Choose the Sheet", accept = c(
".xlsx")),
),
p("Upload Sheet", style="font-weight: bold;"),
box(
width = 200,
tableOutput("content"), style="overflow:
hidden; height: 90px; overflow-y: scroll;
overflow-x: scroll;")
)
),
)
)
# Server
server <- function(input, output, session) {
# Sheet Upload
csv <- reactive({
req(input$file)
inFile <- input$file
df<- read_xlsx(inFile$datapath)
return(df)
})
# Archive Without Extension
output$my_file <- renderText({
# Test if file is selected
if (!is.null(input$file)) {
return(str_replace(input$file$name, '\\.xlsx', ' ') )
} else {
return(NULL)
}
})
# Show Datasheet
output$content <- renderTable({
req(input$file)
inFile <- input$file
read_excel(inFile$datapath, sheet = 1, col_names = TRUE,
col_types = NULL, na = "", skip = 0)
})
output$calfa <-
renderPrint({
int<-csv()[,c(5,6,7,8,9,10)]
names(int)
})
}
# App
shinyApp(ui = ui, server = server)
I have the shiny dashboard below in which if I give a name except of the default consent.name,give the password makis and press the Get started an rmd output is generated.
As you will see while the report is being created a loading message is displayed. The issue is that this loading message is displayed before doing anything at all and this is confusing. How can this loading message be displayed only when the Name and Password inputs are correct and the Get started actionButton() is pushed? I believe that the loading message created with withLoader() should be moved from the ui to the server part of the code in order to follow the same logic as the rmarkdown uiOutput().
the ex.rmd
---
title: "An example Knitr/R Markdown document"
output: pdf_document
---
{r chunk_name, include=FALSE}
x <- rnorm(100)
y <- 2*x + rnorm(100)
cor(x, y)
and the app.
library(shiny)
library(shinydashboard)
library(shinydashboardPlus)
library(shinyjs)
library(knitr)
library(shinycustomloader)
dbHeader <- dashboardHeaderPlus(
titleWidth = "0px",
tags$li(a(
div(style="display: inline;margin-top:25px; padding: 0px 0px 0px 1250px;vertical-align:top; width: 150px;", actionButton("well", "Welcome")),
),
class = "dropdown")
)
shinyApp(
ui = dashboardPagePlus(
header = dbHeader,
sidebar = dashboardSidebar(width = "0px",
sidebarMenu(id = "sidebar", # id important for updateTabItems
menuItem("Welcome", tabName = "well", icon = icon("house"))
) ),
body = dashboardBody(
useShinyjs(),
tags$script(HTML("$('body').addClass('fixed');")),
tags$head(tags$style(".skin-blue .main-header .logo { padding: 0px;}")),
tabItems(
tabItem("well",
fluidRow(),
tags$hr(),
tags$hr(),
fluidRow(
fluidRow(textInput("name", label = ("Name"), value = "consent.name")),
passwordInput("pwd", "Enter the Database browser password"),
withLoader(uiOutput('markdown'),type="html",loader = "loader1"),
actionButton("button", "Get started",style='padding:4px; font-size:140%')
))
)
)
),
server<-shinyServer(function(input, output,session) {
hide(selector = "body > div > header > nav > a")
observeEvent(input$button,{
if (input$name=="consent.name"){
return(NULL)
}
else{
if(input$pwd=="makis"){
output$markdown <- renderUI({
HTML(markdown::markdownToHTML(knit('ex.rmd', quiet = TRUE)))
})
}
else{
return(NULL)
}
}
})
}
)
)
The problem on my shiny app is the action button not working, when i clicked the button it not run. i have created shiny app to classification dataset with neuralnet. I also want to add withprogress in my app. I have tried but its failed.
Thx and sorry for my bad english language
This My ui.R
library(shiny)
library(shinycssloaders)
library(shinyWidgets)
library(shinythemes)
# Define UI
shinyUI(fluidPage(
theme = shinytheme("superhero"),
tags$head(tags$style(".header{background-image:url('tes3.jpg')}
#title{
color: white;
text-align: center;
} ")),
tags$div(class="header",
titlePanel(
fluidRow(
column(3, img(height = 80, width = 80, src = "undip.png")),
column(5, tags$div(id="title","Klasifikasi Neural Network Dengan Alghoritm Backpropagation")),
column(2),
column(1, img(height = 80, width = 195, src = "statistika.png"))
)
),
tags$style(HTML("
.dataTables_wrapper .dataTables_length,
.dataTables_wrapper .dataTables_filter,
.dataTables_wrapper .dataTables_info,
.dataTables_wrapper .dataTables_processing,
.dataTables_wrapper .dataTables_paginate {
color: #ffffff;
}
thead {
color: #ffffff;
}
tbody {
color: #000000;
}
"
))
),
sidebarLayout(
sidebarPanel(
h4(strong("Tentang Aplikasi"),style="text-align:center"),
div(
p("Gui ini digunakan untuk melakukan klasifikasi data biner
dengan menggunakan jaringan syaraf tiruan dengan
optimasi Backpropagation.",style="text-align:center")
),
# Input: Select a file ----
fileInput("file1", h1("Choose CSV File",align="center",
style = "font-size:30px;"),
multiple = FALSE,
accept = c("text/csv",
"text/comma-separated-values,text/plain",
".csv")),
# Horizontal line ----
tags$hr(),
# Input: Checkbox if file has header ----
checkboxInput("header", "Header", TRUE),
# Input: Select separator ----
radioButtons("sep", "Separator",
choices = c(Comma = ",",
Semicolon = ";",
Tab = "\t"),
selected = ","),
# Input: Select quotes ----
radioButtons("quote", "Quote",
choices = c(None = "",
"Double Quote" = '"',
"Single Quote" = "'"),
selected = '"'),
),
mainPanel(
tags$head(
tags$style(type='text/css',
".nav-tabs {font-size: 20px} ")),
tabsetPanel(
tabPanel("Data", span(style = "color:white",
DT::dataTableOutput("contents"))),
tabPanel("Analisis",
uiOutput("respon",),
conditionalPanel("Fungsi Aktivasi",
selectInput("activhid", "Fungsi Aktivasi Hidden Layer:",
choices= c("logistic", "tanh"))
),
numericInput('train', 'Persentase Data Training (%) :',80),
numericInput('hidden', 'Jumlah Neuron Di Hidden Layer:',10),
numericInput('stepmax', 'Jumlah Iterasi Maksimal:',1e6),
numericInput('lrate', 'Nilai Learning Rate:',0.01),
numericInput('threshold', 'Nilai Threshold:',0.01),
numericInput("randseed",
"Random seed:",
sample(1:1e5, size= 1)),
br(),
actionButton("action", "Predict!")
),
tabPanel("Hasil", withSpinner(verbatimTextOutput("hasil"))),
tabPanel("Nilai Prediksi", div(style = "color:black;font-size: 50%; width: 50%",withSpinner(DT::dataTableOutput("prediksi")))),
tabPanel("Plot",
h4(strong("Arsitektur Neural Network"),style="text-align:center"),
withSpinner(plotOutput("plot1", width = "100%"))
)
)
)
),
hr(),
div(
p("~~~Copyright#2019~~~",style="text-align:center"),
p("By Gustiyan Islahuzaman ",style="text-align:center")
)
)
)
this my server.R
library(shiny)
library(neuralnet)
library(OneR)
library(caret)
library(DT)
shinyServer(function(input, output,session) {
dInput <- reactive({
in.file <- input$file1
if (is.null(in.file)){
return(NULL)
}else
df <- read.csv(input$file1$datapath,
header = input$header,
sep = input$sep,
quote = input$quote)
})
output$contents <- DT::renderDataTable({
d.input <- datatable(dInput(),class = 'cell-border stripe')
d.input
})
output$respon <- renderUI({
df <- dInput()
if (is.null(df)) return(NULL)
items=names(df)
names(items)=items
selectInput("respon","Memilih Variabel Respon:",items)
})
observeEvent(input$action,{
set.seed(input$randseed)
f <- reactive({as.formula(paste(input$respon, "~ ."))})
actfct = reactive({paste(input$activhid)})
hid =reactive({as.numeric(paste(input$hidden))})
lrate=reactive({as.numeric(paste(input$lrate))})
d <-as.data.frame(req(dInput()))
d[,input$respon] <- as.integer(d[,input$respon])
d <- na.omit(d)
normalize <- function(x) {
return ((x - min(x)) / (max(x) - min(x)))
}
d<-as.data.frame(lapply(d, normalize))
sampel<-reactive({ sample(1:nrow(d), (input$train/100) * nrow(d))})
train<-d[sampel(),]
test<- d[-sampel(),]
fit <-reactive({ neuralnet(f(), data = train,algorithm = "backprop",learningrate =lrate() ,
hidden = hid(),act.fct =actfct(),lifesign = "full",linear.output=FALSE)
})
output$hasil<-renderPrint({
pred<- round(predict(fit(), test))
nn<-fit()
print(nn$result.matrix)
out=eval_model(pred, test)
})
output$plot1<-renderPlot({
plot(fit(),rep="best")
})
output$prediksi<-DT::renderDataTable({
pred<-round(predict(fit(), test))
tabel<-cbind(Nilai_Aktual=test[,input$respon],NIlai_Prediksi=c(pred))
})
})
})
I created the main dashboard already in R using the shinydashboard package. However, my main question is how do I upload an Excel Csv file (which contains all the data) into the dashboard? I have been trying to figure this out and I am having trouble. So far, I have the following script:
install.packages("shinydashboard")
library(shinydashboard)
ui <- dashboardPage(
dashboardHeader(title = "Analysis Project"),
dashboardSidebar(
menuItem("Dashboard", tabName = "dashboard"),
menuItem("Filter Page"),
menuItem("Data")
),
dashboardBody(
tabItems(
tabItem(tabName = "dashboard")
)
)
)
server <- function(input,output) { }
shinyApp(ui, server)
How about doing it this way?
library(shiny)
library(readxl)
ui <- fluidPage(
fileInput('file1', 'Insert File', accept = c(".xlsx")),
textInput('file1sheet','Name of Sheet (Case-Sensitive)'),
tableOutput("value")
)
server <- function(input, output) {
sheets_name <- reactive({
if (!is.null(input$file1)) {
return(excel_sheets(path = input$file1$datapath))
} else {
return(NULL)
}
})
output$value <- renderTable({
if (!is.null(input$file1) &&
(input$file1sheet %in% sheets_name())) {
return(read_excel(input$file1$datapath,
sheet = input$file1sheet))
} else {
return(NULL)
}
})
}
shinyApp(ui, server)
Try to make a code like that !
library(shiny)
library(shinydashboard)
header <- dashboardHeader(
title = "Analysis Project"
)
sidebar <- dashboardSidebar(
menuItem(text = "Importing file", tabName = "dashboard",icon = icon("file"),
menuSubItem(text = "Importing file", tabName = "dataset")
),
menuItem("Dashboard", tabName = "dashboard"),
menuItem("Filter Page"),
menuItem("Data")
)
body <- dashboardBody(
fluidPage(
tabItems(
tabItem(tabName = "dataset",
fluidRow(
box(width = 12,
fileInput(inputId = "file",
label = "Choose a file",
accept = c(".xlsx",".csv")
),
tableOutput(outputId = "Contents"),
verbatimTextOutput(outputId = "Data")
)
)
)
)
)
)
ui <- dashboardPage(header = header,
sidebar = sidebar,
body = body)
server <- function(input, output, session) {
output$Data <- renderPrint({
if(is.null(input$file)){
print("Import Excel data file")
} else {
inFile <- input$file
df <- read_excel(inFile$datapath)
print(df)
}
})
}
shinyApp(ui = ui, server = server)