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)
Related
I am just learning R. I have a small project where a timetable is displayed and the user has the possibility to enter a subject.
My problem: I do not know how to enter a subject (for example "math") in the timetable (dataframe). As soon as the user presses the action button, the subject should be entered in the table at the position ["1", "monday"].
I tried it here by:
output$my_table <- renderDataTable(df())
df <- eventReactive(input$button, {
timetable["1", "monday"] <- input$select1
})
which unfortunately does not work. Any tips and advice on how I can enter something into a table would be greatly appreciated!
This is my Code:
library(shiny)
ui <- fluidPage(
theme = bs_theme(version = 4, bootswatch = "minty"),
titlePanel(h1("My timetable", align = "center" )),
sidebarLayout(
position = c("left"),
sidebarPanel(
width = 4,
selectInput("select1", label = h5("Event:"),
choices = c("math" , "sience", "sport") ,
selected = 1,
width = 400),
actionButton("action", label = "Add")),
mainPanel(
width = 8,
tableOutput('my_table')),
),
)
and the server:
server <- function(input, output, session) {
output$my_table = renderTable({timetable<- data.frame(monday <- c("","","","",""),
tuesday <- c("","","","",""),
wednesday <- c("","","","",""),
thursday <- c("","","","",""),
friday <- c("","","","",""))},
bordered = TRUE,
spacing = c('l'),
width = "100%",
striped = TRUE,
align = 'c',
rownames = TRUE)
output$timetable <- renderDataTable(df())
df <- eventReactive(input$action, { timetable["1","monday"] <- input$select1 })
}
shinyApp(ui, server)
Here is a complete working example that may be helpful.
First, I might define a separate reactiveVal to store your data.frame. This will be accessible in both your table output as well as either observeEvent or eventReactive methods.
When you reference your reactiveVal, use timetable() with parentheses at the end. When you want to replace the data.frame stored in timetable, you can do timetable(new_data_frame_here). In the observeEvent, I created a temporary tmp data.frame that can be used to edit further for convenience.
library(shiny)
library(bslib)
ui <- fluidPage(
theme = bs_theme(version = 4, bootswatch = "minty"),
titlePanel(h1("My timetable", align = "center" )),
sidebarLayout(
position = c("left"),
sidebarPanel(
width = 4,
selectInput("select1", label = h5("Event:"),
choices = c("math" , "sience", "sport") ,
selected = 1,
width = 400),
actionButton("action", label = "Add")),
mainPanel(
width = 8,
tableOutput('my_table')
)
)
)
server <- function(input, output, session) {
timetable <- reactiveVal(
data.frame(monday = c("","","","",""),
tuesday = c("","","","",""),
wednesday = c("","","","",""),
thursday = c("","","","",""),
friday = c("","","","",""))
)
output$my_table = renderTable(timetable(),
bordered = TRUE,
spacing = c('l'),
width = "100%",
striped = TRUE,
align = 'c',
rownames = TRUE)
observeEvent(input$action, {
tmp <- timetable()
tmp[1, "monday"] <- input$select1
timetable(tmp)
})
}
shinyApp(ui, server)
I am currently learning R. I have a small project where a timetable is displayed and the user has the option to enter a subject.
After adding the subject to the timetable, it should be possible to click on it to open the modalDialog.
Unfortunately my code does not work. I have tried it here:
observeEvent(input$mytable_cells_selected, {
showModal(modalDialog(
title = "Somewhat important message",
"This is a somewhat important message.",
easyClose = TRUE,
footer = NULL))
})
Can someone help me and tell where my error is?
ui <- fluidPage(
theme = bs_theme(version = 4, bootswatch = "minty"),
titlePanel(h1("My timetable", align = "center" )),
sidebarLayout(
position = c("left"),
sidebarPanel(
width = 4,
selectInput("select1", label = h5("Event:"),
choices = c("math" , "sience", "sport") ,
selected = 1,
width = 400),
actionButton("action", label = "Add")),
mainPanel(
width = 8,
tableOutput('mytable')),
),
)
and server:
server <- function(input, output, session) {
timetable <- reactiveVal(
data.frame(monday = c("","","","",""),
tuesday = c("","","","",""),
wednesday = c("","","","",""),
thursday = c("","","","",""),
friday = c("","","","",""))
)
output$mytable <- renderTable(timetable(),
bordered = TRUE,
spacing = c('l'),
width = "100%",
striped = TRUE,
align = 'c',
rownames = TRUE,
selection = list(target = 'cell'))
observeEvent(input$action, {
tmp <- timetable()
tmp[1, "monday"] <- input$select1
timetable(tmp)
})
observeEvent(input$mytable_cells_selected, {
showModal(modalDialog(
title = "message",
"This is a somewhat important message.",
easyClose = TRUE,
footer = NULL))
})
}
shinyApp(ui, server)
As mentioned in the comment, you can use the DT library. Here is a complete example.
Use dataTableOutput in your ui for your data table.
In server, you can include renderDataTable and customize here. In this case, selection is set for single cells.
You can capture the selection event (or can capture clicked event) with input$my_table_cells_selected. In my version I used an underscore for my_table. This information will include the row and column values of the cell selected.
Note that the DT data table could be editable and allow for other interactivity, depending on your needs.
library(shiny)
library(bslib)
library(DT)
ui <- fluidPage(
theme = bs_theme(version = 4, bootswatch = "minty"),
titlePanel(h1("My timetable", align = "center" )),
sidebarLayout(
position = c("left"),
sidebarPanel(
width = 4,
selectInput("select1", label = h5("Event:"),
choices = c("math" , "sience", "sport") ,
selected = 1,
width = 400),
actionButton("action", label = "Add")),
mainPanel(
width = 8,
dataTableOutput('my_table')
)
)
)
server <- function(input, output, session) {
timetable <- reactiveVal(
data.frame(monday = c("","","","",""),
tuesday = c("","","","",""),
wednesday = c("","","","",""),
thursday = c("","","","",""),
friday = c("","","","",""))
)
output$my_table = renderDataTable(timetable(), selection = list(mode = "single", target = "cell"))
observeEvent(input$action, {
tmp <- timetable()
tmp[1, "monday"] <- input$select1
timetable(tmp)
})
observeEvent(input$my_table_cells_selected, {
req(input$my_table_cells_selected)
showModal(modalDialog(
title = "message",
paste("This is a somewhat important message:",
input$my_table_cells_selected[1],
input$my_table_cells_selected[2]),
easyClose = TRUE,
footer = NULL))
})
}
shinyApp(ui, server)
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))
I have constructed an interactive scatterplot in Shiny. Using plotly, I can select groups of points and render the annotations for this group in a table next to the plot.
library(survival)
library(survminer)
mtcars <- get(data("mtcars"))
attach(mtcars)
mtcars$OS <- sample(100, size = nrow(mtcars), replace = TRUE)
mtcars$status <- sample(0:1, size = nrow(mtcars), replace = TRUE)
library(shiny)
library(shinydashboard)
ui <- dashboardPage(
dashboardHeader(),
dashboardSidebar(
sidebarMenu(
menuItem("Test1", tabName = "test1"),
menuItem("Test2", tabName = "test2"),
menuItem("Test3", tabName = "test3"),
radioButtons("radio", h3("Choose groups"),
choices = list("Group 1" = 1, "Group 2" = 2,
"Group 3" = 3),selected = 1),
actionButton("action", "Reset")
)
),
dashboardBody(
tabItems(
tabItem(tabName = "test1",
fluidRow(
column(6,plotlyOutput("plot")),
column(width = 6, offset = 0,
DT::dataTableOutput("brush"),
tags$head(tags$style("#brush{font-size:11px;}")))
)
)
)
)
)
server <- shinyServer(function(input, output, session) {
output$plot <- renderPlotly({
key <- row.names(mtcars)
p <- ggplot(data=mtcars, aes(x=wt,y=mpg,key=key)) +
geom_point(colour="grey", size=2, alpha=1, stroke=0.5)
ggplotly(p) %>% layout(height = 500, width = 500, dragmode = "select")
})
output$brush <- DT::renderDataTable({
d <- event_data("plotly_selected")
req(d)
DT::datatable(mtcars[unlist(d$key), c("mpg", "cyl", "OS", "status")],
options = list(lengthMenu = c(5, 30, 50), pageLength = 30))
}
)
})
shinyApp(ui, server)
Example:
enter image description here
I would like to be able to select (lasso or rectangle) groups of points and display the survival curves between these groups (and p-value if possible) in a separate plot below the table. For example, the user would select 'Group1' on the menu to the left, then outline the desired groups of points, then selct 'Group 2' and select a second group of points, and so on. After each selection, the survival curves appear below the table. Once finished (and would like to restart a new comparison, the user hits 'Reset'). Here's an example output:
Example:
Expected Shiny output
I really don't know where to begin with how to incorporate this. Any help would be great, thank you
See the code below for one possible way to implement this. Throughout, rv is a reactiveValues object holding the data in a data.frame data_df. The group column in data_df tracks group membership as points are selected in the plot, and takes values of 1, 2, 3, or NA depending on whether the row is in one of the three groups. (Note: the groups are assumed to be non-overlapping.)
When the user changes the radio button selection, the plotly selection rectangle should disappear in order to prepare for the selection of the next set of points - the code below uses the shinyjs library to accomplish this, as well as to reset plotly_selected to NULL (otherwise the next rectangular selection will fail to register if it selects the same set of points as the previous one).
library(survival)
library(survminer)
library(plotly)
library(shiny)
library(shinydashboard)
library(shinyjs)
mtcars <- get(data("mtcars"))
attach(mtcars)
mtcars$OS <- sample(100, size = nrow(mtcars), replace = TRUE)
mtcars$status <- sample(0:1, size = nrow(mtcars), replace = TRUE)
jsCode <- "shinyjs.resetSel = function() { Plotly.restyle(plot, {selectedpoints: [null]});}"
ui <- dashboardPage(
dashboardHeader(),
dashboardSidebar(
sidebarMenu(
menuItem("Test1", tabName = "test1"),
menuItem("Test2", tabName = "test2"),
menuItem("Test3", tabName = "test3"),
radioButtons("radio", h3("Choose groups"),
choices = list("Group 1" = 1, "Group 2" = 2,
"Group 3" = 3), selected = 1),
actionButton("action", "Reset all Groups"),
br(),
uiOutput("currentSelections")
)
),
dashboardBody(
useShinyjs(),
extendShinyjs(text = jsCode, functions = c("resetSel")),
tabItems(
tabItem(tabName = "test1",
fluidRow(
column(6,plotlyOutput("plot")),
column(width = 6, offset = 0,
DT::dataTableOutput("brush"),
tags$head(tags$style("#brush{font-size:11px;}")))
),
fluidRow(
column(6),
column(6, plotOutput("survivalCurve"))
)
)
)
)
)
server <- shinyServer(function(input, output, session) {
## mtcars data.frame with an extra group column (initially set to NA)
rv <- reactiveValues(data_df = mtcars %>% mutate(group = NA))
## when a selection is made, assign group values to data_df based on selected radio button
observeEvent(
event_data("plotly_selected"), {
d <- event_data("plotly_selected")
## reset values for this group
rv$data_df$group <- ifelse(rv$data_df$group == input$radio, NA, rv$data_df$group)
## then re-assign values:
rv$data_df[d$key,"group"] <- input$radio
}
)
## when reset button is pressed, reset the selection rectangle
## and also reset the group column of data_df to NA
observeEvent(input$action, {
js$resetSel()
rv$data_df$group <- NA
})
## when radio button changes, reset the selection rectangle and reset plotly_selected
## (otherwise selecting the same set of points for two groups consecutively will
## not register the selection the second time)
observeEvent(input$radio, {
js$resetSel()
runjs("Shiny.setInputValue('plotly_selected-A', null);")
})
## draw the main plot
output$plot <- renderPlotly({
key <- row.names(mtcars)
p <- ggplot(data=mtcars, aes(x=wt,y=mpg,key=key)) +
geom_point(colour="grey", size=2, alpha=1, stroke=0.5)
ggplotly(p) %>% layout(height = 500, width = 500, dragmode = "select")
})
## for each group, show the number of selected points
## (not required by the rest of the app but useful for debugging)
output$currentSelections <- renderUI({
number_by_class <- summary(factor(rv$data_df$group, levels = c("1","2","3")))
tagList(
h5("Current Selections:"),
p(paste0("Group 1: ",number_by_class[1], " points selected")),
p(paste0("Group 2: ",number_by_class[2], " points selected")),
p(paste0("Group 3: ",number_by_class[3], " points selected"))
)
})
output$brush <- DT::renderDataTable({
d <- event_data("plotly_selected")
req(d)
DT::datatable(mtcars[unlist(d$key), c("mpg", "cyl", "OS", "status")],
options = list(lengthMenu = c(5, 30, 50), pageLength = 30))
})
## draw survival curves if a point has been selected
## if none have been selected then draw a blank plot with matching background color
output$survivalCurve <- renderPlot({
if (any(c(1,2,3) %in% rv$data_df$group)) {
fit <- survfit(Surv(mpg, status) ~ group,
data = rv$data_df)
ggsurvplot(fit, data = rv$data_df, risk.table = FALSE)
} else {
par(bg = "#ecf0f5")
plot.new()
}
})
})
shinyApp(ui, server)
I am using googleway library in Shiny R.
The heatmap displays correctly, but I cannot change the heatmap options. If I uncomment the block code where I try to change options, the app crashes.
Here is the part of the code that works, with the offending lines commented out.
library(googleway)
library(magrittr)
library(shiny)
library(shinydashboard)
# Define UI for app
header1 <- dashboardHeader(
title = "My Dashboard"
)
sidebar1 <- dashboardSidebar(
sidebarMenu(
fileInput("file0", "Choose CSV File",
multiple = TRUE,
accept = c("text/csv",
"text/comma-separated-values,text/plain",".csv")),
sliderInput("opacity", "Opacity:",
min = 0, max = 1,
value = 0.5, step = 0.05),
sliderInput("radius", "Radius:",
min = 0, max = 50,
value = 25),
sliderInput("blur", "Blur:",
min = 0, max = 1,
value = 0.75, step = 0.05),
sliderInput("maxvalue", "MaxValue:",
min = 0, max = 1,
value = 1, step = 0.05)
) #sidebarMenu
) #dashboardSidebar
body1 <- dashboardBody(
fluidRow(
tabBox(
title = "TabBox Title 1",
id = "tabset1", height = "400px", width = 11,
selected = "Tab1",
tabPanel("Tab1",
google_mapOutput("Map1")
),
tabPanel("Tab2", "Tab content 2")
) #box
) #fluidRow
) #dashboardBody
ui <- dashboardPage(header1, sidebar1, body1)
# Define data
df <- data.frame(lat = c(14.61),
lon = c(-90.54),
weight = c(100))
# Define SERVER logic
server <- function(input, output, session) {
map_key <- "my_key"
## https://developers.google.com/maps/documentation/javascript/get-api-key
## plot the map
output$Map1 <- renderGoogle_map({
google_map(key = map_key, data = df, zoom = 2, search_box = F) %>%
add_heatmap(weight = "weight") #%>%
#add_traffic()
}) #renderGoogle_map
observeEvent(input$opacity, {
# THIS PART IS COMMENTED OUT BECAUSE THE APP CRASHES
# google_map_update(map_id = "Map1") %>%
# update_heatmap(data = df, option_opacity = input$opacity)
}) #observeEvent
} #server
# Run app
shinyApp(ui, server)
Your help with this will be greatly appreciated! :)
You can use a reactive({}) to carry the input$opacity value and pass it directly to add_heatmap() to achieve the opacity responsiveness.
This can still be done inside the google_map_update(), but you'd have to clear the heatmap layer first, otherwise you'd just be adding layers on top of each other.
server <- function(input, output, session) {
map_key <- "your_key"
## https://developers.google.com/maps/documentation/javascript/get-api-key
opacity <- reactive({
return(input$opacity)
})
## plot the map
output$Map1 <- renderGoogle_map({
google_map(key = map_key, data = df, zoom = 2, search_box = F) %>%
add_heatmap(weight = "weight") #%>%
#add_traffic()
}) #renderGoogle_map
observeEvent(input$opacity, {
google_map_update(map_id = "Map1") %>%
clear_heatmap() %>%
add_heatmap(data = df, option_opacity = opacity())
})
}
} #server