Use reactive variables in regular functions R shiny - r

I'm trying to build a bilingual dashboard. In this dashboard I want to choose the right language column (either ENG or NL) based on input$language. This column serves as the levels input for a function in which a plotly graph is made.
The problem is now that when I use the radiobutton and change the language, nothing changes in the plotly graph. I'm guessing the regular function is not updating when something changes in the 'custom_levels_lang' reactive variable.
How can I make this work?
server.R
library(shinydashboard)
library(dplyr)
library(tidyr)
library(shiny)
library(plotly)
#make bilangual df
ID = c("level_1_graph1","level_1_graph1")
NL = c("Ja","Nee")
ENG = c("Yes","No")
levels_lang = data.frame(ID,NL,ENG)
#create df for pie-chart
S <- c("Ja","Nee")
n <- c(645,544)
percentage <- c(54,46)
df <- data.frame(S,n,percentage)
function(input, output, session) {
# Creating levels by language
custom_levels_lang <- reactive({
#select chosen language for input$language, then transpose all levels per
#graph number to separate columns
#gives custom_levels_lang$'name'
df <- levels_lang %>%
select(ID,one_of(input$language)) %>%
mutate(row = row_number()) %>%
spread_("ID",input$language)
#make list
df <- as.list(df)
#remove na's from list
df <- lapply(df, function(x) x[!is.na(x)])
return(df)
})
#create pie-chart
plot_pie <- function(custom_levels){
plt <- renderPlotly({
#give right levels based on chosen language
levels(df$S) <- custom_levels
#construct plot
df %>%
plot_ly(
labels = df$S,
values = ~percentage,
type = 'pie',
hole = 0.5,
textinfo = 'percent',
text = ~paste("n = ", n),
hoverinfo = 'text') %>%
layout(
showlegend = TRUE,
legend = list(x = 0.2, y = -0.3),
title = "title") %>%
config(
displaylogo = FALSE,
collaborate = FALSE,
modeBarButtonsToRemove = list('zoom2d','pan2d','zoomIn2d','zoomOut2d',
'autoScale2d','resetScale2d','toggleHover',
'toggleSpikelines','hoverClosestCartesian','hoverCompareCartesian'))
})
return(plt)
}
output$plt1 <- plot_pie(custom_levels = custom_levels_lang()$level_1_graph1)
}
ui.R
library(shinydashboard)
library(dplyr)
library(tidyr)
library(shiny)
library(plotly)
header <- dashboardHeader(
title = "Welcome",
titleWidth = 450)
sidebar <- dashboardSidebar(width = 300, radioButtons("language", label = "Kies taal", choices = list("Nederlands" = "NL", "English" ="ENG"), selected = "NL"))
body <- dashboardBody( plotlyOutput('plt1') )
dashboardPage(header,sidebar,body)

The renderPlotly function has to be outside the function call so that it gets notified whenever its dependency (custom_levels_lang()$level_1_graph1) changes.
In your code it's not in a reactive context, so it only gets rendered once.
plot_pie <- function(custom_levels){
#give right levels based on chosen language
levels(df$S) <- custom_levels
#construct plot
plt <- df %>%
plot_ly(
labels = df$S,
values = ~percentage,
type = 'pie',
hole = 0.5,
textinfo = 'percent',
text = ~paste("n = ", n),
hoverinfo = 'text') %>%
layout(
showlegend = TRUE,
legend = list(x = 0.2, y = -0.3),
title = "title") %>%
config(
displaylogo = FALSE,
collaborate = FALSE,
modeBarButtonsToRemove = list('zoom2d','pan2d','zoomIn2d','zoomOut2d',
'autoScale2d','resetScale2d','toggleHover',
'toggleSpikelines','hoverClosestCartesian','hoverCompareCartesian'))
return(plt)
}
output$plt1 <- renderPlotly(plot_pie(custom_levels = custom_levels_lang()$level_1_graph1))

Related

R shiny webapp - webapp runs & works locally but returns error when running app or deploying app to rshiny

This is my code. I am trying to create an interactive webapp where the user can add new data by drawing polygons and then the
I don't understand the error it returns when trying to click 'Run App' in RSTudio or deploy the app to shinyapps (as it works locally when I just run the code). Does someone have an idea why it doesn't work when running or deploying?
## install required packages (if not installed yet)
require(class)
require(dplyr)
require(leafem)
require(leaflet)
require(leaflet.extras)
require(raster)
require(rgdal)
require(rsconnect)
require(sf)
require(sp)
require(shiny)
#### 0. Import Data ####
## import landfills clusters spatial data (point data)
landfills_clusters <- readOGR("plasticleakagewebapp/data/landfill_clusters.gpkg")
landfills_clusters_sf <- st_read('plasticleakagewebapp/data/landfill_clusters.gpkg')
### import landfill polygons
landfills_polygons <- readOGR("plasticleakagewebapp/data/landfills/OpenLandfills_Vietnam.shp", use_iconv = T, encoding = "UTF-8")
## import shapefile of vietnam
vietnam <- readOGR("plasticleakagewebapp/data/vietnam/vietnam.shp")
#### 1. Interactive Map (Leaflet) ####
## plot map with landfills colored by cluster
# e.g. plot water distance < 500m in red
# create color palette
cof <- colorFactor(c("green","blue","red"), domain = c("1","2","3"))
map <- leaflet(landfills_clusters_sf) %>%
addProviderTiles(providers$Esri.WorldImagery) %>%
setView(lng = 105.48, lat = 15.54, zoom = 6) %>%
addMiniMap %>%
addPolygons(data = vietnam, fill = F, weight = 2, color = "#FFFFCC", group = "Outline") %>%
addPolygons(data = landfills_polygons, fill = F, weight = 2, color = "#FFFFCC") %>%
addCircleMarkers(data = landfills_clusters_sf, color = ~cof(km_cluster_unstand), radius = sqrt(landfills_clusters_sf$area_ha)*2,
fillOpacity = 0.5, label = ~name, group = "Risk") %>%
addLegend("bottomleft", colors= c("red","blue","green"), labels=c("high", "medium", "low"), title = "Leakage Risk")
map
#### Interactive Map ####
ui_inter <- fluidPage("Classification the Plastic Leakage Risk of Landfills in Vietnam", id = "nav",
tabPanel("Interactive Map",
div(class = "outer",
# If not using custom CSS, set height of leafletOutput to a number instead of percent
leafletOutput("map", width = "1700px", height = "800px"),
absolutePanel(id = "controls", class = "panel panel-default", fixed = T,
draggable = T, top = 60, left = "auto", right = 20, bottom = "auto",
width = 350, height = "auto",
h2("Plastic Leakage Risk"),
plotOutput("histRain", height = 200),
plotOutput("histWind", height = 200),
),
)
),
tabPanel("Data Explorer",
hr(),
# display the data in an interactive table
DT::dataTableOutput("landfills"),
textInput('Long', 'Enter new landfill longitude'),
textInput('Lat', 'Enter new landfill latitude'),
actionButton("update", "Update Table")
)
)
df <- landfills_clusters_sf[-c(2,9:10,12,16:17)] # select relevant columns
## add long & lat coordinates
df$long <- st_coordinates(landfills_clusters_sf)[,1]
df$lat <- st_coordinates(landfills_clusters_sf)[,2]
server_inter <- function(input, output, session) {
## create interactive map with leaflet
output$map <- renderLeaflet({
map %>%
# add toolbox to draw polygons
addDrawToolbar(
targetGroup = "drawnPoly",
rectangleOptions = F,
polylineOptions = F,
markerOptions = F,
editOptions = editToolbarOptions(selectedPathOptions = selectedPathOptions()),
circleOptions = F,
circleMarkerOptions = F,
polygonOptions = drawPolygonOptions(showArea = T, repeatMode = F, shapeOptions =
drawShapeOptions(fillColor = "orange", clickable = T))) %>%
addStyleEditor()
})
latlongs <- reactiveValues() # temporary to hold coords
latlongs$df2 <- data.frame(Longitude = numeric(0), Latitude = numeric(0))
## create empty reactive spdf to store drawn polygons
value <- reactiveValues()
value$drawnPoly <- SpatialPolygonsDataFrame(SpatialPolygons(list()), data = data.frame(notes=character(0), stringsAsFactors = F))
# fix the polygon to start another
observeEvent(input$map_draw_new_feature, {
coor <- unlist(input$map_draw_new_feature$geometry$coordinates)
Longitude <- coor[seq(1,length(coor), 2)]
Latitude <- coor[seq(2,length(coor), 2)]
isolate(latlongs$df2 <- rbind(latlongs$df2, cbind(Longitude, Latitude)))
poly <- Polygon(cbind(latlongs$df2$Longitude, latlongs$df2$Latitude))
polys <- Polygons(list(poly), ID = input$map_draw_new_feature$properties$`_leaflet_id`)
spPolys <- SpatialPolygons(list(polys))
print(spPolys)
value$drawnPoly <- rbind(value$drawnPoly, SpatialPolygonsDataFrame(spPolys, data = data.frame(notes = NA, row.names = row.names(spPolys))))
## add polygons to landfills polygons df
test <- SpatialPolygonsDataFrame(spPolys, data = data.frame(name = 1:length(spPolys), row.names = row.names(spPolys)))
test#data$area <- NA
test#data$Notes <- NA
test#data$location <- NA
test#proj4string <- CRS("+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs")
new_polygons <- rbind(landfills_polygons, test)
## export new & old landfills to shapefile
shapefile(x = new_polygons, filename = "plasticleakagewebapp/data/landfill/OpenLandfills_Vietnam_total.shp", overwrite = T)
shapefile(x = test, filename = "plasticleakagewebapp/data/landfills/OpenLandfills_Vietnam_new.shp", overwrite = T)
## run DataPreparation script to calculate data of new landfill
source("plasticleakagewebapp/plasticleakage_datapreparation.R")
## import outcome of script
variables <- readOGR("plasticleakagewebapp/data/landfill_variables.gpkg")
# basic landfills as training data
train <- landfills_clusters#data[,c(7:8,11,13:15)]
# newly created landfills (from webapp) as testing data
test <- variables#data[,c(7:8,11,13:14)]
# predict risk class/cluster of new landfill (without re-running clustering algorithm)
knnClust <- class::knn(train = train[,-6], test = test, k = 1, cl = train$km_cluster_unstand)
knnClust
## add cluster as row
variables$km_cluster_unstand <- knnClust
# drop not needed columns
landfills_clusters$risk <- NULL
landfills_clusters$risk_label <- NULL
# combine all landfills into one spdf
new_variables <- rbind(landfills_clusters, variables)
## save results as shapefile
st_write(st_as_sf(new_variables), "plasticleakagewebapp/landfill_clusters_total.gpkg", overwrite = T, append = F)
## update plot upon ending draw
observeEvent(input$map_draw_stop, {
#replot it - take off the DrawToolbar to clear the features and add it back and use the values from the SPDF to plot the polygons
leafletProxy('map') %>%
removeDrawToolbar(clearFeatures = T) %>% removeShape('temp') %>% clearGroup('drawnPoly') %>%
addPolygons(data = value$drawnPoly, group = 'drawnPoly', color = "blue", layerId = row.names(value$drawnPoly)) %>%
addDrawToolbar(
targetGroup = "drawnPoly",
rectangleOptions = F,
polylineOptions = F,
markerOptions = F,
editOptions = editToolbarOptions(selectedPathOptions = selectedPathOptions()),
circleOptions = F,
polygonOptions=drawPolygonOptions(showArea = T, repeatMode = F, shapeOptions
= drawShapeOptions(fillColor = "orange", clickable = T)))
})
latlongs$df2 <- data.frame(Longitude = numeric(0), Latitude = numeric(0)) # clear df
## plot newly added landfills & risk cluster
leafletProxy("map", session) %>%
#addPolygons(data = landfills_polygons, fill = F, weight = 2, color = "#FFFFCC") %>%
addCircleMarkers(data = variables, color = ~cof(km_cluster_unstand), radius = sqrt(variables$area_ha)*2,
fillOpacity = 0.5, label = ~name, group = "Risk")
})
# create object for clicked marker (=landfill)
observeEvent(input$map_marker_click,{
## click returns clickid, long & lat
click <- input$map_marker_click
# if(is.null(click))
# return()
leafletProxy("map", session) %>% setView(lng = click$lng, lat = click$lat, zoom = 16)
})
# A reactive expression that returns the set of landfills that are in map bounds (to plot reactive graphs)
landfillsInBounds <- reactive({
if (is.null(input$map_bounds))
return(landfills_clusters_sf[FALSE,])
bounds <- input$map_bounds
latRng <- range(bounds$north, bounds$south)
lngRng <- range(bounds$east, bounds$west)
subset(landfills_clusters_sf,
st_coordinates(landfills_clusters_sf)[,2] >= latRng[1] & st_coordinates(landfills_clusters_sf)[,2] <= latRng[2] &
st_coordinates(landfills_clusters_sf)[,1] >= lngRng[1] & st_coordinates(landfills_clusters_sf)[,1] <= lngRng[2])
})
output$histRain <- renderPlot({
# If no zipcodes are in view, don't plot
if (nrow(landfillsInBounds()) == 0)
return(NULL)
hist(landfillsInBounds()$rain,
main = "Weather Data",
xlab = "Average Precipitation (mm)",
xlim = range(landfills_clusters_sf$rain),
col = '#00ffff',
border = 'white')
})
output$histWind <- renderPlot({
# If no landfills are in view, don't plot
if (nrow(landfillsInBounds()) == 0)
return(NULL)
hist(landfillsInBounds()$windspeed,
main = "",
xlab = "Average Wind Speed (km/h)",
xlim = range(landfills_clusters_sf$windspeed),
col = '#00DD00',
border = 'white')
})
output$landfills <- DT::renderDT({
df
})
}
# Run the app
shinyApp(ui_inter, server_inter)
Error which is returend when clicking "Run App" in RStudio:
Fehler in ogrListLayers(dsn = dsn) : Cannot open data source

Make acumalative graphics whit plotly Shiny R

I must design a graph that accumulates variables as they are added in Shiny R using plotly.
For example, if I graph the variable x with respect to the date t with a select input, I add the variable and it is located on the right side of the variable x, indicating with a separator that it is the variable y and so with as many variables are selected.
This is my code:
library(shiny)
library(plotly)
library(dplyr)
set.seed(123)
df <- data.frame(x = seq.Date(as.Date("2000/1/1"), by = "month", length.out = 100),
cat = sample(c("m1","m2","m3"),100, replace = TRUE),
a = cumsum(rnorm(100)),
b = rnorm(100),
c = rnorm(100),
d = rnorm(100))
ui <- fluidPage(
selectInput("x","Variable",names(df)[-1],NULL,TRUE),
selectInput("y", "category", unique(df$cat), NULL, TRUE),
numericInput("ls","limite superior",NULL,-100,100),
numericInput("li","limite superior",NULL,-100,100),
plotlyOutput("plot1")
)
server <- function(input, output, session) {
output$plot1 <- renderPlotly({
req(input$y, input$x)
df <- df%>%
filter(cat %in% input$y)%>%
select(one_of("x",input$x))
estado <- ifelse(df[[2]]>input$ls,"red",
ifelse(df[[2]]<input$ls & df[[2]]>input$li,
"orange","green"))
df$estado <- estado
p <- plot_ly(df,
x = ~x,
y = ~df[[2]],
type = "scatter",
mode = "lines")
## Makers
p <- p %>%
add_trace(x = ~x,
y= df[[2]],
marker = list(color = ~estado, size = 20, symbol = "square"),
showlegend = FALSE)
## Lengends and labels
p <- p %>%
layout(legend = list(orientation = 'h'))%>%
layout(title = paste('Comportamiento de calidad de agua residual', input$estacion, sep=' '),
plot_bgcolor = "#e5ecf6",
xaxis = list(title = 'Fecha'),
yaxis = list(title = paste(input$x,"mg/l", sep=" ")))
print(p)
})
}
shinyApp(ui, server)
I need that when adding the variables a, b, c, d, the graph will be made just after the variable that was already there so that it looks something like this:
Use subplot and do function.
df %>%
group_by(category) %>%
do(p = plot_ly(...) %>% (plot_features...)) %>%
subplot(sharex= FALSE,sharey=TRUE, nrow=1, margin = 0.0001)
With plot feautures i mean all the deatils of the plot (markers, lines, colors, etc)

Interactive heatmap in R using apexcharter fails at reactivity

at the moment I try to create an interactive heatmap in R with apexcharter. This works fine at manual chart creation but fails on interactive use within shiny.
library(shiny)
library(tidyverse)
library(apexcharter)
# Define UI for application that draws a histogram
ui <- fluidPage(
# Application title
titlePanel("Test Heatmap"),
# Sidebar with a slider input for number of bins
sidebarLayout(
sidebarPanel(
selectInput(
inputId = "heatmap_filter",
label = "heatmap filter",
choices = c(1999, 2008),
selected = 2008
)
),
mainPanel(
apexchartOutput("heatmap")
)
)
)
# Define server logic required to draw a histogram
server <- function(input, output) {
output$heatmap <- renderApexchart({
df <- mpg %>% filter(year == input$heatmap_filter) %>% mutate_if(is.character, as.factor) %>% group_by(manufacturer, class) %>% summarise(cnt = n()) %>% tidyr::complete(class, fill = list(cnt = 0))
q20 <- round(as.numeric(quantile(df %>% filter(cnt>0) %>% pull(cnt), probs = seq(0,1,0.2), na.rm = TRUE))[2],0)
q40 <- round(as.numeric(quantile(df %>% filter(cnt>0) %>% pull(cnt), probs = seq(0,1,0.2), na.rm = TRUE))[3],0)
q60 <- round(as.numeric(quantile(df %>% filter(cnt>0) %>% pull(cnt), probs = seq(0,1,0.2), na.rm = TRUE))[4],0)
q80 <- round(as.numeric(quantile(df %>% filter(cnt>0) %>% pull(cnt), probs = seq(0,1,0.2), na.rm = TRUE))[5],0)
apex(
data = df,
type = "heatmap",
mapping = aes(x = manufacturer, y = class, fill = cnt)
) %>%
ax_dataLabels(enabled = TRUE) %>%
ax_plotOptions(
heatmap = heatmap_opts(
enableShades = FALSE,
colorScale = list(
ranges = list(
list(from = 0, to = q20, color = "#106e45"), #grün
list(from = q20, to = q40, color = "#90dbba"), #leichtes grün
list(from = q40, to = q60, color = "#fff33b"), #gelb
list(from = q60, to = q80, color = "#f3903f"), # orange
list(from = q80, to = 20, color = "#e93e3a") #rot
)
)
)
) %>%
ax_title(
text = paste("Test interactive heatmap",
input$heatmap_filter
), align = "center"
)
})
}
# Run the application
shinyApp(ui = ui, server = server)
With the manual approach everthing works as expected. But when I change the input select only the values changes but not the heatmap quantil ranges and not the title input. Its seems like the input value is not pushing the changes to already calculated variables. I already tried to use an reactive df or reactive variables but so far nothing works.
I added a minimal example where you could change the year input and this should change the title and the color ranges.
Can you help me?
Thanks in advance.
Try setting auto_update to FALSE in the call to apex
apex(
data = df,
type = "heatmap",
auto_update = FALSE,
...

plot_ly plot from dplyr breaks down at input from Shiny SelectInput

I'm just learning Shiny.
Here's the code that doesn't work (along with some sample data built-in):
library(tidyverse)
library(shiny)
library(plotly)
library(shinyjs)
analysis_df<- data.frame(
report_month = c("jan","jan","jan","jan","jan","jan"),
payee_id = c("59","59","59","59","59","59"),
Payee = sample(LETTERS[1:5],6,replace = TRUE),
Attrib_1 = sample(LETTERS[6:10],6,replace = TRUE),
Attrib_2 = sample(LETTERS[11:15],6,replace = TRUE),
country_of_sale_iso2 = c("AU","AU","AU","NZ","AU","AU"),
currency = c("USD","USD","USD","USD","USD","USD"),
Attrib_3 = c("Pandora-AU","Pandora-AU","Pandora-AU","Pandora-AU","Pandora-AU","Pandora-AU"),
month_paid = c("jun","jun","jun","jun","jun","jun"),
Attrib_4 = sample(LETTERS[16:20],6,replace = TRUE),
Attrib_5 = sample(LETTERS[21:25],6,replace = TRUE),
units = c("2","8","6","2","10","4"),
gross = c("0.003254785","0.013019141","0.009764356","0.003254785","0.016273926","0.00650957"),
reserves_wh = c("0","0","0","0","0","0"),
rsrv_liq = c("0","0","0","0","0","0"),
Attrib_7 = c("0.002753548","0.011014193","0.008260645","0.002753548","0.013767741","0.005507097"),
Attrib_8 = c("3.25E-04","0.001301914","9.76E-04","3.25E-04","0.001627393","6.51E-04"),
Attrib_9 = c("1.76E-04","7.03E-04","5.27E-04","1.76E-04","8.79E-04","3.52E-04"),
Attrib_10 = c("0.03","0.03","0.03","0.03","0.03","0.03"),
Attrib_11 = c("1","1","1","1","1","1"),
Attrib_12 = c("0.003254785","0.013019141","0.009764356","0.003254785","0.016273926","0.00650957")
)
attribs <- c("Attrib_1","Attrib_2","Attrib_3","Attrib_4")
payees <- analysis_df %>% distinct(Payee) %>% as.vector()
ui <- fluidPage(
headerPanel("Product Explorer"),
sidebarPanel(
selectInput('slice_by', 'Color the Bars By:', choices = attribs, selected = "Attrib_1"),
sliderInput('plotHeight', 'Adjust Chart Size',
min = 100, max = 2000, value = 425)
),
mainPanel(
plotlyOutput('Plot', height = "900px")
)
)
server <- function(input, output) {
output$Plot <- renderPlotly({
col_cht <- analysis_df %>%
filter(payee_id == 59) %>%
plot_ly(x = ~report_month,
y = ~gross) %>%
add_bars(color = input$slice_by) %>%
layout(barmode = "stack",
height = input$plotHeight)
})
}
shinyApp(ui, server)
I want the SelectInput to work, and it doesn't.
However, if I replace
add_bars(color = input$slice_by) %>%
with
add_bars(color = ~Attrib_1) %>%
i.e., hard-code it, the plot looks the way it should.
When you are piping with
> analysis_df %>%
the analysis_df dataframe is passed to the functions. So when using ~Attrib_1 you are passing the values in the Attrib_1 column, which are
# > analysis_df$Attrib_1
# [1] H J J H H G
So the plot gets different colors for the levels in analysis_df$Attrib_1.
When you are using input$slice_by that returns only one value, the value selected in Select. So you are getting just one color in the plot.
To get it to work use
color = analysis_df[, input$slice_by]
If you don't want to use analysis_df inside pipe, search about Non-standard Evaluation in R. With lazyeval you can do this,
color = interp(~x, x = as.name(input$slice_by))

R ggvis linked_brush is not reactive

I have the following code on my Server. R
data_agg_plot1<- reactive({
brush1 <- linked_brush(keys = data_agg()$id, "navy" )
data_agg <- data_agg()
plot1<-data_agg%>%
ggvis(x = ~dates_all) %>%
group_by(factor(dates_all.1)) %>%
layer_points(y = ~ value, fill =~dates_all.1, shape =~dates_all.1) %>%
layer_paths(y = ~ value, stroke = ~dates_all.1 , strokeOpacity := 0.5) %>%
scale_ordinal("fill", range = c("green", "red", "blue"))%>%
scale_ordinal("shape", range = c("triangle-up","triangle-down","circle")) %>%
scale_ordinal("stroke",range=c("green","red","blue")) %>%
brush1$input() %>%
hide_legend(c('stroke','fill'))%>%
add_legend(c('shape','fill'),
title = "Symbol", orient = "left",
values = c("New hires", "Attrition" , "Net Growth"),
properties = legend_props(
title = list(fontSize = 16))) %>%
add_axis("x",properties= axis_props(labels = list(angle=60,align = "left")),
tick_padding =0,
title = "") %>%
add_axis("y", title = "Total Count") %>%
set_options(width = "auto",height = 400) %>%
scale_numeric('y',clamp = TRUE)
return(list(plot1,brush1))
})
so this is a reactive function that returns me a list of 2 functions, a plot and my brush object.
the purpose of doing so is so that I can make my keys reactive - this is so that I can make an additional plot based on my user's selection. think of it as the second plot depends on what the first user highlights in the first plot.
this is my following code:
plot1_data<-reactive({
data_agg_plot1()[[1]]
})
plot1_data%>%bind_shiny("plot1")
selected_plot1 <- reactive({
data_agg_plot1()[[2]]
})
output$test <- renderPrint({
temp <- selected_plot1()$selected()
print(temp)
})
however, when I print out the selection, it is all false,
please refer to the image below:
can anybody explain to me how to overcome this?
I highly suspect I have to re-write my linkedbrush function,
I have tried both solutions from:
linked_brush in ggvis cannot work in Shiny when data change
but it does not work.

Resources