Shiny/R: turn columns into checkbox - r

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)

Related

Shiny: Show Download Button Only If An Action Button Is Pressed

I have a reactive data frame df1(). A user can add their initials as text inputs such that the text is filled to rows as a new column name when the user clicks the Add button.
Everything works fine but I would like to add one more thing:
Make the download button download show only if the action button bttn1 is pressed. Currently download is shown regardless of pressing bttn1.
I can't understand why the following is not working:
observe({
if (is.null(input$bttn1)) {shinyjs::hide("download")}
else {shinyjs::show("download")}
})
The following is a fully working code:
##### ui
ui <- dashboardPage(
skin = "black",
#### Upper navigation bar
dashboardHeader(
title = "title",
titleWidth = 230
),
#### Side bar
dashboardSidebar(disable = T),
#### Body
dashboardBody(
shinyjs::useShinyjs(),
tabsetPanel(
tabPanel(
### tab1
tabName = "tab1",
h5("Tab 1"),
fluidRow(
reactableOutput("table1"),
textInput("textinput1", "Initials:"),
actionButton("bttn1", "Add", class = "btn-primary"),
reactableOutput("table2"),
uiOutput("ui_download")
) # fluidRow
), # tabPanel
#### tab2
tabPanel(
tabName = "tab2",
h5("Tab 2"),
fluidRow(
) # fluidRow
) # tabPanel
) # tabsetPanel
) # dashboardBody
) # dashboardPage
#### server
server <- function(input, output, session) {
## df1
# reactive
df1 <- reactive({
data.frame(
"id" = c("A", "A", "A", "A"),
"num1" = c(10, 11, 12, 13)
)
})
# renderReactable
output$table1 <- renderReactable({
reactable(df1(), borderless = F, defaultColDef = colDef(align = "center"))
})
## df2
## Text input
rv1 <- reactiveValues()
observe({
if (nrow(df1()) == 0) {shinyjs::hide("bttn1")}
else {shinyjs::show("bttn1")}
})
observe({
if (nrow(df1()) == 0) {shinyjs::hide("textinput1")}
else {shinyjs::show("textinput1")}
})
observeEvent(input$bttn1, {
rv1$values <- df1()
rv1$values$name <- input$textinput1
})
rv1_text <- reactive({
rv1$values
})
output$table2 <- renderReactable({
req(rv1_text())
reactable(rv1_text(), borderless = F, defaultColDef = colDef(align = "center"))
})
## downloadButton
# renderUI
output$ui_download <- renderUI({
# req(rv1_text())
downloadButton("download", "Download")
})
**# Why isn't this working?**
observe({
if (is.null(input$bttn1)) {shinyjs::hide("download")}
else {shinyjs::show("download")}
})
# Download csv
output$download <- downloadHandler(
filename = function() {
paste0('data', '.csv')
},
content = function(file) {
write.csv(rv1_text(), file, row.names = F)
}
)
}
shinyApp(ui, server)
I couldn't run your codes since you did not share the libraries you used in. But If I understand you correctly, conditionalPanel is very suitible for your purpose.
Here is a small shiny app that you can adapt it to your codes:
library(shiny)
ui <- fluidPage(
actionButton("call_download", "Show Download Button"),
conditionalPanel(condition = "input.call_download == 1",
downloadLink('downloadData', 'Download')
)
)
server <- function(input, output) {
output$downloadData <- downloadHandler(
filename = function() {
paste('data-', Sys.Date(), '.csv', sep='')
},
content = function(con) {
write.csv(mtcars, con)
} )
}
shinyApp(ui, server)

Select column from dataframe using shiny widget and modify its name using textInput()

In the app below I want to select a column name from the selectInput() and then modify it using the textInput().The update will happen after the actionButton click.
library(shiny)
library(shinydashboard)
library(DT)
iris2 <- iris # make a copy, don't want mess up internal dataset
ui <- dashboardPage(
dashboardHeader(),
dashboardSidebar(
fileInput("file1", "Choose CSV File",
accept = c(
"text/csv",
"text/comma-separated-values,text/plain",
".csv")
),
uiOutput("column"),
textInput("text", label = "Set column name", placeholder = "Enter text..."),
actionButton("sub","submit")
),
dashboardBody(
dataTableOutput("process")
)
)
server <- function(input, output) {
raw<-reactive({
inFile <- input$file1
if (is.null(inFile))
return(NULL)
read.csv(inFile$datapath, header = T)
})
raw2<-reactive({
inFile <- input$file1
if (is.null(inFile))
return(NULL)
read.csv(inFile$datapath, header = T)
})
output$column<-renderUI({
selectInput("col","Pick a column to change its name",
choices = colnames(raw2()))
})
mydf <- reactiveValues(df = raw2(), names = names(raw2()))
observeEvent(input$sub, {
req(input$text)
mydf$names[mydf$names == input$col] <- input$text
names(mydf$df) <- mydf$names
updateSelectInput(inputId = "col", choices = mydf$names)
})
output$process<-renderDataTable({
mydf$df
})
}
shinyApp(ui, server)
Here is how to fix
library(shiny)
library(shinydashboard)
library(DT)
iris2 <- iris # make a copy, don't want mess up internal dataset
ui <- dashboardPage(
dashboardHeader(),
dashboardSidebar(
selectInput("col","Pick a column to change its name",
choices = colnames(iris2)),
textInput("text", label = "Set column name", placeholder = "Enter text..."),
actionButton("sub","submit")
),
dashboardBody(
tags$style(type="text/css",
".shiny-output-error { visibility: hidden; }",
".shiny-output-error:before { visibility: hidden; }"
),
dataTableOutput("process")
)
)
server <- function(input, output) {
mydf <- reactiveValues(df = iris2, names = names(iris2))
observeEvent(input$sub, {
req(input$text)
mydf$names[mydf$names == input$col] <- input$text
names(mydf$df) <- mydf$names
updateSelectInput(inputId = "col", choices = mydf$names)
})
output$process<-renderDataTable({
mydf$df
})
}
shinyApp(ui, server)

How to create a button that will create a pdf file of a table

I currently have a table being generated and I would like the user to be able to create a pdf file when they click the download button.
I am currently getting an error where when I click the download button I get an html file that downloads the entire page of the app. I thought that using pdf(file) would work but it ignores the function.
Here is currently what I have.
library(shiny)
library(xlsx)
library(shinyWidgets)
population <- read.xlsx("population.xlsx", 1)
fieldsMandatory <- c("selectedCountry")
labelMandatory <- function(label) {
tagList(
label,
span("*", class = "mandatory_star")
)
}
appCSS <-
".mandatory_star {color: red;}"
ui <- fluidPage(
navbarPage(title = span("Spatial Tracking of COVID-19 using Mathematical Models", style = "color:#000000; font-weight:bold; font-size:15pt"),
tabPanel(title = "Model",
sidebarLayout(
sidebarPanel(
shinyjs::useShinyjs(),
shinyjs::inlineCSS(appCSS),
div(
id = "dashboard",
pickerInput(
inputId = "selectedCountry",
labelMandatory ("Country"),
choices = population$Country,
multiple = FALSE,
options = pickerOptions(
actionsBox = TRUE,
title = "Please select a country")
),
sliderInput(inputId = "agg",
label = "Aggregation Factor",
min = 0, max = 50, step = 5, value = 10),
actionButton("go","Run Simulation"),
)
),
mainPanel(
tabsetPanel(
tabPanel("Input Summary", verbatimTextOutput("summary"),
tableOutput("table"),
downloadButton(outputId = "downloadSummary", label = "Save Summary"))
)
)
)
)
)
)
server <- function(input, output, session){
observeEvent(input$resetAll, {
shinyjs::reset("dashboard")
})
values <- reactiveValues()
values$df <- data.frame(Variable = character(), Value = character())
observeEvent(input$go, {
row1 <- data.frame(Variable = "Country", Value = input$selectedCountry)
row2 <- data.frame(Variable = "Aggregation Factor", Value = input$agg)
values$df <- rbind(row1, row2)
})
output$table <- renderTable(values$df)
observe({
# check if all mandatory fields have a value
mandatoryFilled <-
vapply(fieldsMandatory,
function(x) {
!is.null(input[[x]]) && input[[x]] != ""
},
logical(1))
mandatoryFilled <- all(mandatoryFilled)
# enable/disable the submit button
shinyjs::toggleState(id = "go", condition = mandatoryFilled)
})
output$downloadSummary <- downloadHandler(
filename = function(file) {
paste('my-report.pdf', )
},
content = function(file) {
pdf(file)
}
)
}
shinyApp(ui,server)
Here's a minimal example:
library(shiny)
ui <- fluidPage(
downloadButton("savepdf", "Save pdf")
)
server <- function(input, output, session) {
output$savepdf <- downloadHandler(
filename = "test.pdf",
content = function(file) {
pdf(file)
plot(iris$Sepal.Length, iris$Sepal.Width)
dev.off()
}
)
}
shinyApp(ui, server)
Also see here.
Here is a minimal example with the package latexpdf. It will create the pdf table in the folder of the app.
library(shiny)
library(latexpdf)
dat <- head(iris, 5)
ui <- fluidPage(
br(),
actionButton("dwnld", "Create pdf"),
tableOutput("mytable")
)
server <- function(input, output, session){
output[["mytable"]] <- renderTable({
dat
})
observeEvent(input[["dwnld"]], {
as.pdf(dat)
})
}
shinyApp(ui, server)

How can we add groupby taking inputs from the user from the table we have uploaded?

I am trying to take input from the user for group_by and count of the data on the columns selected by the user from the uploaded CSV file. In short, the user should select the columns he needs to group_by and getting the count of the data
I am able to upload the file and getting the summary in the load section, I have created a prep column for this group_by part.
library(shiny)
library(shinydashboard)
library(ggplot2)
library(DT)
ui<-dashboardPage(
dashboardHeader(title = "Model"),
dashboardSidebar(
sidebarMenu(id="tabs",
menuItem("Data", tabName = "data", icon = icon("table"),startExpanded = TRUE,
menuSubItem("Load", tabName = "data1"),
menuSubItem("Prep", tabName = "prep")
),
menuItem("Visualisation",icon=icon("bar-chart-o"), tabName = "vis"),
menuItem("Result", icon=icon("cog"), tabName = "result")
)
),
dashboardBody(
tags$style(type="text/css",
".shiny-output-error { visibility: hidden; }",
".shiny-output-error:before { visibility: hidden; }"
),
tabItems(
tabItem(tabName = "data1",
fluidPage(
fluidRow(
fileInput("file1","Choose CSV File",
accept = c("text/csv",
"text/comma-seperated-values, text/plain",
".csv")
),
tags$hr(),
checkboxInput("header", "Header", TRUE),
radioButtons("sep","Separator",
choices=c(Comma=",",
semicolon=";",
Tab="\t"),
selected = ";")
),
mainPanel(
uiOutput("tb")
)
)
)
),
tabItem(tabName = "prep",
fluidPage(
fluidRow(
mainPanel(
uiOutput("Pre")
)
)
))
)
)
server <- shinyServer(function(input,output){
data <- reactive({
file1 <- input$file1
if(is.null(file1)){return()}
read.csv(file = file1$datapath, sep=input$sep)
})
output$filedf <- renderTable({
if(is.null(data())){return()}
input$file1
})
output$sum <- renderTable({
if(is.null(data())){return()}
summary(data())
})
output$table <- renderTable({
if(is.null(data())){return()}
data()
})
output$tb <- renderUI({
if(is.null(data())){return()}
tabsetPanel(tabPanel("About file", tableOutput("filedf")),tabPanel("Data", tableOutput("table")),tabPanel("Summary", tableOutput("sum")))
})
#----- Data Preparation------
output$Pre <- renderUI({checkboxGroupInput(inputId = "select_vars",
label="Select Variables",
choices = names(filedf))
})
filedf_sel <- reactive({
req(input$select_vars)
filedf_sel<- data()%>% select(input$select_var)
})
})
shinyApp(ui,server)
the output should be the result of the group_by and count on the columns selected by the user
1) Create a place for user to choose the columns. As you're using user data for it, ?renderUI seems like an OK option for me. Something like this should do:
output$group_by_selection <- renderUI({
req(data())
selectizeInput(
'group_by_select', 'Group by', choices = colnames(data()), multiple = TRUE
),
It should be in the server.R file. Use uiOutput('group_by_selection') in ui.R to show it.
Now, you need to group and count the data after user is done selecting. You can do it by button press or whatever. It can look like this, using data.table library for easy grouping and counting:
grouped_data <- eventReactive(input$group_by_button, {
if (length(input$group_by_select) > 0 ) {
data()[, Count := .N, by = input$group_by_select]
} else {
NULL
}
})

make conditionalPanel appears when RData file is loaded in shinydashboard

I am making a shiny app that interacts with a big data.frame that I have stored as an RData file. I want the user to select the file, and once the RData is completely loaded (takes ~15 seconds) a second panel should show up allowing the user to input some sample name and do some operations.
Here is how my app looks now
header <- dashboardHeader(title="Analysis and database")
sidebar <- dashboardSidebar(
useShinyjs(),
sidebarUserPanel(),
hr(),
sidebarMenu(
# Setting id makes input$tabs give the tabName of currently-selected tab
id = "sidebarmenu",
menuItem("Analyse old data by Sample", tabName="oldfile", icon = icon("table"), startExpanded = FALSE),
fileInput(inputId = "file1", "Choose database file"),
conditionalPanel(
#condition = "input.sidebarmenu === 'oldfile'",
condition = "output.fileUploaded == 'true' ",
textInput(inputId = "sample", label ="Type a sample ID"),
actionButton("go2", "Filter")
)
)
)
body <- dashboardBody(
tags$style(type="text/css",
".shiny-output-error { visibility: hidden; }",
".shiny-output-error:before { visibility: hidden; }"),
tabItems(
tabItem("oldfile", "Sample name data.table",
fluidRow(DT::dataTableOutput('tabla_oldfile') %>% withSpinner(color="#0dc5c1")))
)
)
ui <- dashboardPage(header, sidebar, body)
### SERVER SIDE
server = function(input, output, session) {
options(shiny.maxRequestSize=100000*1024^2)
prop <- reactive({
if (input$go2 <= 0){
return(NULL)
}
result <- isolate({
if (is.null(input$file1))
return(NULL)
if (is.null(input$sample))
return(NULL)
inFile <- input$file1
print(inFile$datapath)
#big_df <- load(inFile$datapath)
print (big_df)
print(input$sample)
oldtable <- big_df1 %>% filter_at(vars(GATK_Illumina.samples:TVC_Ion.samples),
any_vars(stringi::stri_detect_fixed(., as.character(input$sample))))
oldtable
})
result
})
output$fileUploaded <- reactive({
return(!is.null(prop()))
})
outputOptions(output, 'fileUploaded', suspendWhenHidden=FALSE)
output$tabla_oldfile <- DT::renderDataTable({
DT::datatable(prop(),
filter = 'top',
extensions = 'Buttons',
options = list(
dom = 'Blftip',
buttons =
list('colvis', list(
extend = 'collection',
buttons = list(list(extend='csv',
filename = 'results'),
list(extend='excel',
filename = 'results'),
list(extend='pdf',
filename= 'results')),
text = 'Download'
)),
scrollX = TRUE,
pageLength = 5,
lengthMenu = list(c(5, 15, -1), list('5', '15', 'All'))
), rownames = FALSE
)
})
}
shinyApp(ui, server)
I have used the solution provide in Make conditionalPanel depend on files uploaded with fileInput but I can't make it work, there is another implementation using shinyjs package but don't know how to use it on my example

Resources