I'm having issues with a filter option in my R shinydashboard app. I'm able to filter a dataframe column (padj < 1) but when I incorporate this same filter into the app the data is missing padj rows that are very tiny like 1.41103072458963E-14. I get all rows up to 4 decimal places (0.00011014) but not rows with padj smaller than that. This cuts off dozens of wanted rows.
I may be coding something wrong and have tried searching for similar issues but haven't found any.
The select input I chose is:
pickerInput("FDR", "False Discovery Rate", choices = c(1, 0.1, 0.05, 0.01))
when I try to filter using above input:
genes1 <- reactive({
genes <- DEG2 %>% dplyr::filter(padj <= input$FDR) %>% dplyr::filter(log2FoldChange >= input$FC | log2FoldChange <= -input$FC)
})
Any help/advice is greatly appreciated.
data to be loaded here:
datafile.
See below for the app code.
library(shinydashboard)
library(dashboardthemes)
library(shiny)
library(shinythemes)
library(shinyWidgets)
library(shinycssloaders)
library(shinyjs)
library(htmlTable)
library(DT)
library(dplyr)
library(ggpubr)
library(ggplot2)
library(htmlwidgets)
library(plotly)
library(table1)
# load dataset
DEG2 <- read.csv("DEG2.csv")
# to add color to the spinner
options(spinner.color="#287894")
#############################################
### HEADER #################################
#############################################
header <- dashboardHeader(title = tagList(
tags$span(class = "logo-mini", "Cell"),
tags$span( class = "logo-lg", "My 1st App" )),
titleWidth = 300)
#############################################
### SIDEBAR #################################
#############################################
sidebar <- dashboardSidebar(width = 300, sidebarMenu(id = "sidebar", # id important for updateTabItems
menuItem("Pipeline", tabName = "pipe", icon = icon("bezier-curve")),
menuItem("Something", tabName = "plot", icon = icon("braille")),
menuItem("Something else", tabName = "pathways", icon = icon("connectdevelop")),
menuItem("Contact", tabName = "contact", icon = icon("address-card"))
)
)
#############################################
### BODY #################################
#############################################
body <- dashboardBody(
useShinyjs(), # Set up shinyjs
# changing theme
shinyDashboardThemes(theme = "blue_gradient"),
tabItems(
######### Tab 1 #########################################
tabItem("pipe",
fluidPage(
h2("Pipeline"),
#### STEP 1 ####
box(width = 12, title = "Step1: Filter for DEGs", collapsible = TRUE, collapsed = FALSE, status = "primary", solidHeader = TRUE,
fluidRow(
column(4, offset = 0,
sliderTextInput("FC", "Fold-Change (absolute value)", choices = seq(from= 0, to= 5, by=0.5), grid = TRUE),
pickerInput("FDR", "False Discovery Rate", choices = c(1, 0.1, 0.05, 0.01)),
setSliderColor(color = '#EE9B00', sliderId = 1),),
column(6, offset= 1,
valueBoxOutput("genes_filtered", width = 4))),
br(),
fluidRow(
column(10, offset =0,
DT::dataTableOutput("genetable") %>% withSpinner(type = 8, size=1))),
br(),
actionBttn("step1", "Select to advance:step 2", color = "warning", style = "fill", icon = icon("angle-double-down" ))
)),
#### STEP 2 ####
conditionalPanel(
condition = "input.step1 == 1",
fluidPage(
box(width = 12, title = "Step2: Filter for gene regulation", collapsible = TRUE, collapsed = FALSE, status = "primary", solidHeader = TRUE,
"Choose to subset the genes that are up or down regulated",
br(),
br(),
fluidRow(
column(6, offset = 0,
prettyRadioButtons("reg", "Choose:", choices = c("Up-regulated", "Down-regulated", "All"), status = "success", fill=TRUE, inline = TRUE))
),
br(),
fluidRow(
column(6, offset = 0,
valueBoxOutput("value", width = 6)))
) # box
)
) # conditional panel
)# end tab3
) # end tabItems
)#dashboardBody
ui <- dashboardPage(header = header,
sidebar = sidebar,
body = body
)
server <- function(input, output, session) {
############################################
###### TAB1 ##################
############################################
# step 1
genes1 <- reactive({
genes <- DEG2 %>% dplyr::filter(padj <= input$FDR) %>% dplyr::filter(log2FoldChange >= input$FC | log2FoldChange <= -input$FC)
})
output$genes_filtered <- renderValueBox({
valueBox(value=length(genes1()$symbol), subtitle = "Filtered genes", color = "purple", icon=icon("filter"))
})
output$genetable <- DT::renderDataTable({
genes1() }, server = FALSE, extensions =c("Responsive", "Buttons"), rownames = FALSE, options = list(dom = 'Blfrtip', buttons = list('copy', list(extend = "collection",
buttons = c("csv", "excel", "pdf"),
text = "Download")))
)
# step 2
genes2 <- reactive({
g2 <- if (input$reg == "Up-regulated"){
genes1() %>% filter(log2FoldChange > 0)
} else if (input$reg == "Down-regulated"){
genes1() %>% filter(log2FoldChange < 0)
} else {
genes1()
}
})
output$value <- renderValueBox({
if (input$reg == "Up-regulated"){
valueBox(value = length(genes2()$symbol), subtitle = "Up-regulated genes", color = "red", icon = icon("hand-point-up"))
} else if (input$reg == "Down-regulated"){
valueBox(value = length(genes2()$symbol), subtitle = "Down-regulated genes", color = "blue", icon = icon("hand-point-down"))
} else {
valueBox(value = length(genes2()$symbol), subtitle = "All genes", color = "orange", icon = icon("record-vinyl"))
}
})
} #server
shinyApp(ui, server)
Try as.numeric(input$FDR) in your filter as shown below.
genes <- DEG2 %>% dplyr::filter(padj <= as.numeric(input$FDR))
Related
I am developping a Shiny app relying on VisNetwork to plot dynamic overviews of our company's network.
Since the network is rather large, I'd like that it can extends vertically so as to make it more readable. Currently it works but then the network overlaps with the dashboardSidebar, at the bottom:
See this screenshot.
Why does the dashboardSidebar extends horizontally at the bottom, isn't only supposed to be left-sided ?
Is it possible to remove this footer?
Here is a simple reproducible example (I believe the issue arises when setting up the Height argument of the VisOptions function):
library(shiny)
library(visNetwork)
library(shinydashboard)
# User interface
ui <- dashboardPage(
dashboardHeader(title = "Network", titleWidth = 220),
## Sidebar content
dashboardSidebar(width = 220,
sidebarUserPanel(name = "CTU",image = "unibe_logo_mh.png"),
sidebarMenu(id = "tab",
menuItem('CTU Division',
menuSubItem("Data Management", tabName = "datamanagement", icon = icon("database")),
menuSubItem("Statistics", tabName = "statistics", icon = icon("chart-area")),
menuSubItem("Clinical Study Management", tabName = "studymanagement", icon = icon("laptop-medical")),
menuSubItem("Monitoring", tabName = "monitoring", icon = icon("check")), # Would like to use the "magnifying-glass"
menuItem("Quality Management", tabName = "qualitymanagement", icon = icon("broom"))),
radioButtons("projectlab", label = "Project labels", choices = c("IDs", "Names"), inline=T),
selectInput("servicetype", label = "Service", choices = c("\a", "Basic", "Full", "Light")),
checkboxGroupInput('projecttype', "Project types", c("External", "Consulting","Internal","FTE"), selected = "External"),
selectInput("dlfsupport", label = "DLF support", choices = c("\a", "Yes", "No")),
selectInput("cdms", label = "CDMS", choices = c("\a","REDCap", "secuTrial", "Webspirit")),
checkboxGroupInput('tables', "Export tables", c("Time Bookings","Workers","Projects"), selected = c("Time Bookings","Workers","Projects")),
downloadButton("DownloadReport", "Download Report", style = "margin: 5px 5px 35px 35px; "))),
## Body content
dashboardBody(tags$head(tags$style(HTML(".main-sidebar { font-size: 15px; }"))), # Changing sidebar font sizes
# Boxes need to be put in a row (or column)
fluidRow(
visNetworkOutput("network") # Unique name for an output
))
)
server <- function(input, output, session) {
getDiagramPlot <- function(nodes, edges){
v <- visNetwork(
nodes,
edges
) %>%
visPhysics(stabilization = TRUE, enabled = F) %>%
visOptions(height = "1800", highlightNearest = T, nodesIdSelection = T, selectedBy= list(variable="group",multiple=T)) %>%
visEdges(color = list(highlight = "red")) %>% # The colour of the edge linking nodes
visLayout(improvedLayout = TRUE) %>%
visEdges(arrows = edges$arrows) %>%
visInteraction(multiselect = F) %>%
visEvents(doubleClick = "function(nodes) {
Shiny.onInputChange('current_node_id', nodes.nodes);
;}")
return(v)
}
testFunction <- function(node_id){
print(paste("The selected node ID is:", node_id))
}
nodes <- data.frame(id = 1:3, label = 1:3, group = c("group1","group1","group2"), value = c(10,10,11), color=c("#E41A1C","#48A462","#4A72A6"))
edges <- data.frame(from = c(1,2), to = c(1,3), width = c(0.4,0.8))
output$network <- renderVisNetwork(
getDiagramPlot(nodes, edges)
)
observeEvent(input$current_node_id,{
testFunction(input$current_node_id)
})
}
shinyApp(ui, server)
Best,
C.
I'm trying to create a ShinyApp and hoping I could get some pointers.
I'm trying to get a summary table ("Summary score") to represent either i) the minimum value associated with user input for radio buttons (e.g., Id037_crit1 & Id038_crit1) or the text string "NA" if a checkbox is selected (Id039_crit1).
I'm not sure how to change the code such that the summary table shows either the minimum value for the radio buttons or the character string if the checkbox is selected. I'm assuming there's some kind of if-else statement but I can't get it to work.
library(shinydashboard)
library(shinythemes)
library(shiny)
library(shinyWidgets)
library(DT)
library(tidyverse)
ui <- fluidPage(
theme = shinytheme("united"),
# Application title
titlePanel("TITLE"),
sidebarLayout(
sidebarPanel(
selectInput("select",
label = helpText("Select a critera"),
choices = list("Criteria_1", "Criteria_2"),
selected = c("NULL")
)
),
mainPanel(tabsetPanel(
tabPanel(
"Criteria", conditionalPanel(h3("Question 1", align = "left"),
condition = "input.select == 'Criteria_1'",
prettyRadioButtons(
inputId = "Id037_crit1",
label = "Predictions:",
choices = c(
"Option 1" = 1,
"Option 2" = 2,
"Option 3" = 3
),
inline = TRUE,
status = "danger",
fill = TRUE
),
),
conditionalPanel(h3("Question 2", align = "left"),
condition = "input.select == 'Criteria_1'",
prettyRadioButtons(
inputId = "Id038_crit1",
label = "Hypotheses:",
choices = c(
"Option 1" = 1,
"Option 2" = 2,
"Option 3" = 3
),
inline = TRUE,
status = "danger",
fill = TRUE)
),
conditionalPanel(h3("Or", align = "left"),
condition = "input.select == 'Criteria_1'",
awesomeCheckbox(
inputId = "Id039_crit1",
label = "NA",
status = "danger")
),
# User side-pannel selection - criteria 2
conditionalPanel(h3("Question 1", align = "left"),
condition = "input.select == 'Criteria_2'",
prettyRadioButtons(
inputId = "Id040_crit2",
label = "Methods:",
choices = c(
"Option 1" = 1,
"Option 2" = 2
),
inline = TRUE,
status = "danger",
fill = TRUE)),
# Second Tab --------------------------------------------------------------
tabPanel(
"Summary score",
DTOutput("summary")
),
))
)
)
# SERVER ------------------------------------------------------------------
server <- function(input, output) {
calc_min_val <- function(contains) {
radios_inputid <- str_subset(names(input), contains)
map_dbl(radios_inputid, ~ as.numeric(input[[.x]])) %>%
min()
}
summ <- reactive({
min_values <- c("crit1$", "crit2$") %>%
map(calc_min_val)
tibble(
Lowest_Criteria = c("Specific hypotheses and prediction are provided?", "Predictions regarding the electromagnetic area of
interest are sufficient?"),
value = map(min_values, ~.)
)
})
output$summary <- DT::renderDT({
datatable(summ())
})
# Downloadable csv of selected dataset ----
output$downloadData <- downloadHandler(
filename = function() {
paste("DATA", ".csv", sep = "")
},
content = function(file) {
write.csv(datasettable(summ()), file, row.names = FALSE)
}
)
}
shinyApp(ui, server)
Perhaps you are looking for this
summ <- reactive({
min_values <- c("crit1$", "crit2$") %>%
map(calc_min_val)
if (input$Id039_crit1 & input$select == 'Criteria_1') value = "NA" else value = map(min_values, ~.)
tibble(
Lowest_Criteria = c("Specific hypotheses and prediction are provided?", "Predictions regarding the electromagnetic area of
interest are sufficient?"),
value = value
)
})
I'm having trouble understanding why my condition input.wave1.length > 1 does not work.
What I would like happen is for the checkbox "Overall Curve" to not appear unless input$loess AND if there are more than 1 items checked in the either Wave 1 or Wave 2 accordions.
I don't see what I'm doing wrong. Is there a condition in javascript that will make this work or can this be done with R script?
my app:
library(shiny)
library(shinydashboard)
library(bsplus) #accordion
#########define waves##########
wave1 <- c(
"Cayuga", "Columbia", "Erie", "Greene",
"Lewis", "Putnam", "Suffolk", "Ulster"
)
wave2 <- c(
"Broome", "Chautauqua", "Cortland", "Genesee",
"Monroe", "Orange", "Sullivan", "Yates"
)
ui <- dashboardPage(
dashboardHeader(title = "Example"),
dashboardSidebar(
tags$h4("waves:", style = "margin: 5px;"),
bs_accordion(id = "waves") %>%
#use the entire heading panel as a link instead of just title
bs_set_opts(use_heading_link = TRUE) %>%
bs_append(
title = "Wave 1",
content = checkboxGroupInput(inputId = "wave1", label = NULL,
choices = c(wave1, "All Wave 1"),
selected = "Cayuga")
) %>%
bs_append(
title = "Wave 2",
content = checkboxGroupInput(inputId = "wave2", label = NULL,
choices = c(wave2, "All Wave 2"))
),
br(),
#LOESS CURVE ####
checkboxInput(inputId = "loess", label = "Display Loess Curve",
value = FALSE),
uiOutput("loess_a"),
# uiOutput("loess_overall"),
conditionalPanel(condition = "input.loess == TRUE & input.wave1.length > 1", # should include selected > 1
checkboxInput(inputId = "loessGrouped", label = "Overall Curve",
value = TRUE)
)
),
dashboardBody(
tags$style(HTML('.checkbox label{color: red;}'))
)
)
server <- function(input, output, session) {
# conditional loess smoother #######
output$loess_a <- renderUI({
req(input$loess)
conditionalPanel(condition = "input.loess == TRUE",
sliderInput(inputId = "smoothing", label = NULL,
min = 0, max = 1, value = 1, step = 0.1))
})
}
shinyApp(ui = ui, server = server)
To work with either Wave 1 or Wave 2 accordions having more than 1 item checked, you can use the following:
conditionalPanel(condition = "input.loess == 1 & (input.wave1.length > 1 || input.wave2.length > 1)", # should include selected > 1
checkboxInput(inputId = "loessGrouped", label = "Overall Curve",
value = TRUE)
)
In addition, you still need to make input.loess == 1 on the server side
I have a table being display in a shiny app. I want to format the tables based on the values and color it accordingly. I have seen the formattable area coloring where based on the range of the values it defines the breaks and then color gradients are generated which are applied to the table. What I want to do is allow the user to fill the min and max value and depending on it the values in the table will be colored. So if the values range from 1-20 and if the user inputs are 5 and 15 , values below 5 and above 15 shouldnt have any color gradients applied to them. Below is the code of how I am doing currently using formatable area formatting.
library(shiny)
library(shinyWidgets)
library(shinydashboard)
library(DT)
sidebar <- dashboardSidebar(
sidebarMenu(id = "tab",
menuItem("1", tabName = "1")
)
)
body <- ## Body content
dashboardBody(box(width = 12,fluidRow(
fluidRow( column(
width = 3, textInput("text1", label = h5("Min"), value = "Enter min")),
column(
width = 3, textInput("text2", label = h5("Max"), value = "Enter max"))),
DT::dataTableOutput("op")
)))
ui <- dashboardPage(dashboardHeader(title = "Scorecard"),
sidebar,
body)
# Define the server code
server <- function(input, output,session) {
df <- data.frame(month = c("mazda 3", "mazda cx5", "mazda 6","mazda miata","honda civic","honda accord"),
april = c(.1,.2,.3,.3,.4,.5),
may = c(.3,.4,.5,.2,.1,.5),
june = c(.2,.1,.5,.1,.2,.3))
brks <- reactive({ quantile(df$april, probs = seq(.05, .95, .05), na.rm = TRUE)})
clrs <- reactive({ round(seq(255, 175, length.out = length(brks()) + 1), 0) %>%
{paste0("rgb(",.,",", ., ",255 )")}})
df_format<- reactive ({datatable(df,options = list(searching = FALSE,pageLength = 15, lengthChange = FALSE))%>%
formatStyle(names(df),backgroundColor = styleInterval(brks(), clrs()))})
output$op <-renderDataTable({
df_format()
})
}
shinyApp(ui = ui, server = server)
Here is your working code.
You must use that input minimal and maximal value as limits for your sequence (I just change it to range - is easier for user to put a range like that)
Then you generate sequence - according your notation - brks() - in my case I use length.out of 10 but you can put as many breaks as you want or dynamically.
Then generate on
number of colors - 1
and in the end in styleInterval() for background add limits of white - or any other color you want.
library(shiny)
library(shinyWidgets)
library(shinydashboard)
library(DT)
sidebar <- dashboardSidebar(
sidebarMenu(id = "tab",
menuItem("1", tabName = "1")
)
)
body <- ## Body content
dashboardBody(box(width = 12,fluidRow(
fluidRow(column(
width = 3,
sliderInput("range_value",
label = h3("Put a range value"),
min = 0,
max = 100,
value = c(5, 15)
)
)
),
DT::dataTableOutput("op")
)))
ui <- dashboardPage(dashboardHeader(title = "Scorecard"),
sidebar,
body)
# Define the server code
server <- function(input, output,session) {
df <- data.frame(month = c("mazda 3", "mazda cx5", "mazda 6","mazda miata","honda
civic","honda accord"),
april = c(9, 8, 11,14,16,1),
may = c(3,4,15,12,11, 19),
june = c(2,11,9,7,14,1))
brks <- reactive({
seq(input$range_value[1], input$range_value[2], length.out = 10)
})
clrs <- reactive({ round(seq(255, 175, length.out = length(brks()) - 1), 0) %>%
{paste0("rgb(",.,",", ., ",255)")}})
df_format<- reactive ({datatable(df,options = list(searching = FALSE, pageLength = 15, lengthChange = FALSE)) %>%
formatStyle(names(df),
backgroundColor = styleInterval(c(brks()), c('white', clrs() ,'white'))
)
})
output$op <-renderDataTable({
df_format()
})
}
shinyApp(ui = ui, server = server)
I've built a shinydashboard app. it's working fine but the only problem is that it is not auto-fitting the webpage. Also, when opened in a mobile browser, it shows a desktop site rather than one customized for the mobile. Is there a problem with the bootstrap?
here's my code:
library(shiny)
library(shinyapps)
library(shinydashboard)
library(dygraphs)
library(htmltools)
library(htmlwidgets)
library(metricsgraphics)
library(RColorBrewer)
library(maps)
library(mapproj)
library(ggplot2)
library(dplyr)
library(plyr)
library(ggvis)
library(scales)
library(leaflet)
#library(RJSONIO)
#library(shinybootstrap2)
#shinybootstrap2::withBootstrap2()
#source("helpers.R")
test_bar <- read.csv("test_bar.csv")
channel_bar <- read.csv("channel_bar.csv")
time <- read.csv("time_enroll.csv")
#counties <- readRDS("counties.rds")
ui <- dashboardPage(skin="blue",
dashboardHeader(title="KPI Dashboard"),
dashboardSidebar(
fluidRow(),
fluidRow(),
box(width = 12.5,solidHeader=TRUE,title="Refresh Interval",
status = "warning",
selectInput("interval", "Data Time Period",
choices = c(
"Current Month" = 30,
"3MM" = 60,
"YTD" = 120,
"R12" = 300
),
selected = "30"
)
),
menuItem("", tabName = "widgets"),
menuItem("", tabName = "widgets"),
box(width = 12.5,solidHeader=TRUE,title="Refresh Interval",
status = "warning",
selectInput("interval", "Refresh interval",
choices = c(
"30 seconds" = 30,
"1 minute" = 60,
"2 minutes" = 120,
"5 minutes" = 300,
"10 minutes" = 600
),
selected = "60"
),
uiOutput("timeSinceLastUpdate"),
actionButton("refresh", "Refresh now")
# p(class = "text-muted",
# br(),
# "Source data updates every day."
# )
)
),
dashboardBody(
fluidRow(
infoBox("New Co-Pay Card Users", 100*10, icon = icon("credit-card"), fill = TRUE,color="olive"),
infoBox("Total Co-Pay Card Users", 500*10, icon = icon("credit-card"), fill = TRUE,color="olive"),
infoBox("Total Redemptions", 10000, icon = icon("thumbs-up"), fill = TRUE,color="lime")
),
fluidRow(
box(
title = "Enrollments by Specialty", status = "primary", solidHeader = TRUE,
collapsible = TRUE, width=6,height=315,
plotOutput("plots",click="plot_click1",height=240)
),
box(
title = "Trend", solidHeader = TRUE,status="primary",
collapsible = TRUE,width=6, dygraphOutput("plot2",height=250)
)
),
fluidRow(
box(title = "Enrollments by Channel", status = "primary", solidHeader = TRUE,
collapsible = TRUE, width=6,height=315,
plotOutput("plot_c")),
box(title="Map",
tags$head(tags$style("
.leaflet-container { background-color: white !important; }
")),
leafletMap(
"map", "100%", 500,
# By default OpenStreetMap tiles are used; we want nothing in this case
initialTileLayer = NULL,
initialTileLayerAttribution = NULL,
options=list(
center = c(40, -98.85),
zoom = 4,
maxBounds = list(list(17, -180), list(59, 180))
)
))
))
)
server <- function(input,output,session) {
output$plots <- renderPlot({
ggplot(test_bar,aes(x=factor(Specialty),y=Actual)) +geom_bar(stat="identity")+
theme(panel.background = element_rect(fill="white",
color="white"),panel.grid.major = element_line(color="white"),
axis.title.x=element_blank(),axis.title.y=element_blank())
})
output$plot2 <- renderDygraph({
if (is.null(input$plot_click1$x)) return()
keeprows <- round(input$plot_click1$x) == as.numeric(time$Spec)
time2 <- time[keeprows,]
time3 <- time2[2]
time_ts <- ts(time3$enroll,start=c(2014,1),end=c(2014,12),frequency=12)
dygraph(time_ts) %>% dyRangeSelector(height=20,strokeColor="") %>% dyOptions(fillGraph=TRUE)
})
output$test_table <- renderTable({
if (is.null(input$plot_click1$x)) return()
keeprows <- round(input$plot_click1$x) == as.numeric(time$Spec)
time[keeprows,]
})
output$plot_c <- renderPlot({
print(ggplot(channel_bar,aes(x=factor(Channel),y=Actual)) +geom_bar(stat="identity")+
theme(panel.background = element_rect(fill="white",
color="white"),panel.grid.major = element_line(color="white"),
axis.title.x=element_blank(),axis.title.y=element_blank()))
})
output$map <- reactive(TRUE)
map <- createLeafletMap(session, "map")
# session$onFlushed is necessary to delay the drawing of the polygons until
# after the map is created
session$onFlushed(once=TRUE, function() {
# Get shapes from the maps package
states <- map("state", plot=FALSE, fill=TRUE)
map$addPolygon(states$y, states$x, states$names,
lapply(brewer.pal(9, "Blues"), function(x) {
list(fillColor = x)
}),
list(fill=TRUE, fillOpacity=1,
stroke=TRUE, opacity=1, color="white", weight=1
)
)
})
}
shinyApp(ui, server)
You can try using the code below to control your chart size, place it right after your plotOutput or showOutput function.
HTML('<style>.rChart {width: 100%; height: 500px}</style>')
Example:
fluidRow(
box(
title = "Enrollments by Specialty", status = "primary",
solidHeader = TRUE,
collapsible = TRUE,
width=6,height=315,
plotOutput("plots",click="plot_click1",height=240),
HTML('<style>.rChart {width: 100%; height: 500px}</style>')
)