I have been surfing around this site for answers to my problem with Shiny and Plotly (ggplotly) but none of these has been enough. I'm trying to customize hover boxtext of my ggplotly. I would to include more variables on that boxtext when you put your mouse over any point of my plot.
I have trying with this this solution
Any way to display data frame information besides x and y on hover with shiny/ggplot?
and this one: Shiny: Interactive ggplot with Vertical Line and Data Labels at Mouse Hover Point
Without any successful result
I'm working trying to create visualization for football data, I have this huge df which has the followings variables:
[1] "ID" "Nombre" "Apellido" "Rol"
[5] "Tecnica" "Club" "Competicion" "Nacionalidad"
[9] "PrimerToque" "Dribbling" "Versatilidad" "Pases"
[13] "Centros" "Remate" "TiroLibre" "Cabezazo"
[17] "TiroLejano" "SaqueLateral" "Marcaje" "Penales"
[21] "Tacle" "Corner" "Aceleracion" "Stamina"
[25] "Fuerza" "Agilidad" "Balance" "TendenciaLesion"
[29] "Salto" "FormaNatural" "Velocidad" "FechaNacimiento"
[33] "AnoNacimiento" "CA" "PA" "RepHome"
[37] "RepActual" "RepMundial" "Consistencia" "Altura"
[41] "Peso" "Posicion"
this is my ui file
library("shiny")
library("shinythemes")
library("shinyWidgets")
library("shinydashboard")
library("leaflet")
library("ggplot2")
library("dplyr")
library("ggrepel")
library("plotly")
ui <- shinyUI(fluidPage(
# Application title
titlePanel("Graph"),
sidebarLayout(
sidebarPanel(
selectizeInput("Atributo1", #xaxis
label = "AtributoX",
choices = c("Centros", "Pases", "PrimerToque", "Remate", "Tecnica","Dribbling","TiroLejano",
"TiroLibre", "SaqueLateral","Penales", "Corner" ,"Cabezazo", "Salto", "Aceleracion",
"Stamina", "Fuerza","Agilidad","Balance","TendenciaLesion","FormaNatural","Velocidad",
"Marcaje", "Tacle","Consistencia", "Versatilidad", "CA", "RepHome"), selected ="CA"),
selectizeInput("Atributo2", #yaxis
label = "AtributoY",
choices = c("Centros", "Pases", "PrimerToque", "Remate", "Tecnica","Dribbling","TiroLejano",
"TiroLibre", "SaqueLateral","Penales", "Corner" ,"Cabezazo", "Salto", "Aceleracion",
"Stamina", "Fuerza","Agilidad","Balance","TendenciaLesion","FormaNatural","Velocidad",
"Marcaje", "Tacle","Consistencia", "Versatilidad", "CA", "RepHome")),
sliderInput("numero", "Numero de Jugadores a Mostrar:",
value = 10, min = 1, max = 50, round = TRUE, dragRange = FALSE),
numericInput("Edad1", "Edad:", 42, value = 17),
numericInput("Edad2", "Edad:", 42),
sliderTextInput("Posicion","Posicion" ,
choices = c("GK","DL","DR","DC","DM","MC","ML","MR","AMC", "ST"),
selected = c("MC"), #incase you want all values by default
animate = FALSE, grid = FALSE,
hide_min_max = FALSE, from_fixed = FALSE,
to_fixed = FALSE, from_min = NULL, from_max = NULL, to_min = NULL,
to_max = NULL, force_edges = FALSE, width = NULL, pre = NULL,
post = NULL, dragRange = TRUE),
radioButtons("Color", label = "Color Por:",
choices = list("Club" = "Club", "Division" = "Competicion"),
selected = "Club")
),
mainPanel(
plotlyOutput("distPlot")
)
)
))
and my server file
server <- shinyServer(function(input, output) {
output$distPlot <- renderPlotly({ #Plot tipo Plotly
n <- input$numero
if (is.null(n)) {
n <- 1
}
dfjoin <- readRDS("dfjoin.rds")
a <- reactive({
dfjoin %>% filter(Posicion == input$Posicion) %>% filter(FechaNacimiento >= input$Edad1 & FechaNacimiento <= input$Edad2) %>% top_n(n, CA)
})
p <- ggplot(a(), aes_string(x = input$Atributo1, y = input$Atributo2,
label = "Apellido", colour = input$Color)) +
geom_text(position=position_jitter(h=1,w=1), check_overlap = TRUE) +
labs(colour= input$Color, title= paste("Grafico", input$Atributo1, "/", input$Atributo2, sep =" ")) +
theme(legend.position = "none")
p <- ggplotly(p)
print(p)
})
})
Currently Im getting only default hover information, which is Label, X axis, Y axis and colour. I would like to customize and include another variables as put First Name and Last Name. Which would be something like: paste(Nombre,Apellido, sep = " ")
I tried that line inside Tooltip:
$ggplotly(p, Tooltip = paste(Nombre,Apellido, sep = " "))
but didnt worked neither.
as a tip: in spanish:
Nombre = First Name
Apellido: Last Name
I've been doing that this way:
https://github.com/Bustami/DatoFutbol/blob/master/libertadores2019/shiny-app/server.R
Basically create a new column with all your text of interest (calling variables choosed by user) with HTML syntax and then use it with the "label" parameter inside ggplot and "tooltip" inside ggplotly.
Related
I'm currently trying to make a Shiny app for Leaflet cards with simple translations. Each leaflet card has several base groups that are linked to different variables. To avoid re-rendering the leaflet maps every time the base group changes, I have adopted a function I found here which only changes the fill of the polygons.
As long as I only use one language, the app works without problems, but when multiple translations options are implemented, the app crashes. The problem seems to occur when I try to link input$map_groups to variables needed for colouring.
My code looks like this:
library(shiny)
library(shinyWidgets)
library(leaflet)
library(sf)
library(dplyr)
library(shiny.i18n)
#--- Loading Generic Shape File For Demonstration
shape <- st_read(system.file("shape/nc.shp", package = "sf"),
stringsAsFactors = FALSE) %>%
#--- Mutating Two Variables To Factors As My Map Uses Factors
mutate(One = as.factor(SID74), Two = as.factor(SID79)) %>%
#--- Keep Just This Three Variables
select(c(CNTY_ID, One, Two))
#--- Color Palette For Filling Polygons
scale.color <- colorFactor(palette = "RdYlBu", levels = seq(1:60))
#--- Loading And Rgistering Translation File
lang <- Translator$new(translation_json_path = "./translations.json")
lang$set_translation_language("gb")
language <- c("English", "Deutsch", "Français" , "Español")
#--- Naming Vector For Base Groups And Related Variables
layer_calls <- setNames(c('One', 'Two'), c("First", "Second"))
#--- A Function For Recoloring An Existing Polygon And Related JS-Code
#----- Source: https://github.com/rstudio/leaflet/issues/496#issuecomment-650122985
setShapeStyle <- function(map, data = getMapData(map), layerId, stroke = NULL, color = NULL, weight = NULL,
opacity = NULL, fill = NULL, fillColor = NULL, fillOpacity = NULL, dashArray = NULL,
smoothFactor = NULL, noClip = NULL, options = NULL){
options <- c(list(layerId = layerId),
options,
filterNULL(list(stroke = stroke, color = color, weight = weight, opacity = opacity,
fill = fill, fillColor = fillColor, fillOpacity = fillOpacity,
dashArray = dashArray, smoothFactor = smoothFactor, noClip = noClip)))
# Evaluate All Options
options <- evalFormula(options, data = data)
options <- do.call(data.frame, c(options, list(stringsAsFactors = FALSE)))
layerId <- options[[1]]
style <- options[-1] # drop layer column
leaflet::invokeMethod(map, data, "setStyle", "shape", layerId, style);
}
leafletjs <- tags$head(
tags$script(HTML(
'
window.LeafletWidget.methods.setStyle = function(category, layerId, style){
var map = this;
if (!layerId){
return;
} else if (!(typeof(layerId) === "object" && layerId.length)){ // in case a single layerid is given
layerId = [layerId];
}
//convert columnstore to row store
style = HTMLWidgets.dataframeToD3(style);
//console.log(style);
layerId.forEach(function(d,i){
var layer = map.layerManager.getLayer(category, d);
if (layer){ // or should this raise an error?
layer.setStyle(style[i]);
}
});
};
'
)))
#--- Defining UI
ui <- fluidPage(
leafletjs,
usei18n(lang),
pickerInput(inputId = 'selected_language', width = 125,
choices = c("gb", "de", "fr", "es"),
selected = lang$get_key_translation()),
leafletOutput("map")
)
#--- Defining Server Logic
server <- function(input, output, session){
output$map <- renderLeaflet({
leaflet(data = shape) %>%
#--- Initial Unfilled Polygon Map
addPolygons(layerId = ~CNTY_ID, stroke = TRUE, color = "white", weight = 1.25,
highlightOptions = highlightOptions(stroke = 5, weight = 10)) %>%
#--- Initial Layer Controls
addLayersControl(baseGroups = lang$t(names(layer_calls)))
})
#--- Filling Polygons Based On Base Layer-Variable After Translation
observe({
req(input$selected_language)
update_lang(session, input$selected_language)
leafletProxy("map", data = shape) %>%
#--- This Part Always Crashes Shiny!!!
setShapeStyle(layerId = ~CNTY_ID, fillOpacity = 1)#, fillColor = ~scale.color(get(layer_calls[lang$t(input$map_groups)])))
})
}
# Run the application
shinyApp(ui = ui, server = server)
My basic translation scheme would be provided by a JSON file which looks like this:
{
"languages": [
"gb",
"de",
"fr",
"es"
],
"translation": [
{
"gb": "First",
"de": "Erste",
"fr": "Premier",
"es": "Primera"
},
{
"gb": "Second",
"de": "Zweite",
"fr": "Deuxième",
"es": "Segundo"
}
]
}
In my One-Langue-App I can simply use , fillColor = ~scale.color(get(layer_calls[[input$map_groups]])) to trigger a recoloring after the base group has been changed. Unfortunately, I have no idea how to connect the selected base group to a call of the needed variable to trigger the recoloring. Any kind of help is greatly appreciated!
I'm getting the error message when trying to deploy my shiny flexdashboard that was created with r markdown. Can anyone help? My code is below. Thank you! The data is saved here
The "submit" function seems to be the issue, I read in the random forest model I created so a data table could output once people enter in their desired input variables - but it doesn't seem to be working. The map and the accompanying data table works fine though.
library(readr)
library(tibble)
library(mlbench)
library(tidyverse)
library(leaflet)
library(sf)
library(rgdal)
library(leaflet)
library(ggplot2)
library(dplyr)
library(sp)
library(raster)
library(ggplot2)
library(rgeos)
library(ggthemes)
library(data.table)
library(geojsonR)
library(leaflet.extras)
library(flexdashboard)
library(reshape2)
library(lmtest)
library(htmltools)
library(caret)
library(randomForest)
library(ggcorrplot)
library(lsr)
library(DT)
library(plotly)
library(knitr)
library(crosstalk)
library(shiny)
library(shinydashboard)
setwd("~/SPRING 2022/Data Science for Public Policy/FinalProject/new_DataSets")
risk_map <- readRDS("risk_map.rds")
model <- readRDS("model.rds")
variables <- c("dissim_19","Total_Pop20", "pct_adultsWchild_PH", "mean_pov_idx", "mean_lbr_idx", "mean_trans_idx","recap","CDBG_perCapita")
Fair Housing Plan Risk by County
Row {data-height=400}
Map of Risk Prediction for Fair Housing Plans by County
##0 high risk, 1 medium risk, 2 low risk
#color and for na
pal <- colorFactor(
palette = c("#f03b20",
"#feb24c",
"#ffeda0"),
domain = risk_map#data$predicted_outcome,
na.color = "grey" # desired color for NA polygons on map
)
pal_noNA <- colorFactor(
palette = c("#f03b20",
"#feb24c",
"#ffeda0"),
domain = risk_map#data$predicted_outcome,
na.color = NA
)
risk_popup <- paste("<strong>Predicted Fair Housing Plan Risk Level: </strong>",
risk_map#data$predicted_outcome,"<br><strong>County Name: </strong>",
risk_map#data$county_name, "<br><strong>Total 2020 Population: </strong>",
risk_map#data$Total_Pop20, "<br><strong>CDBG Funding per Capita: </strong>",
risk_map#data$CDBG_perCapita,"<br><strong>2019 White to Non-White Dissimilarity Index: </strong>",
risk_map#data$dissim_19)
risk_map %>%
leaflet::leaflet() %>%
addProviderTiles("CartoDB.Positron") %>%
setView(lat = 39.8283, lng = -98.5795, zoom = 4) %>%
addPolygons(stroke = TRUE,
smoothFactor = 0.2,
fillOpacity = .8,
color = ~pal(predicted_outcome),
weight = 0.5,
popup = risk_popup) %>%
# addAwesomeMarkers(data = results_points,
# lat = ~X,
# lng = ~Y,
# icon = awesome,
# popup = results_popup) %>%
# #fillColor = "black",fillOpacity = 0.5,stroke = F)
leaflet::addLegend("bottomright",
pal = pal_noNA,
values = ~predicted_outcome,
title = "Predicted Risk of Fair Housing Plan Outcome by U.S. County",
opacity = 1) %>%
leaflet::addMeasure()
Row {data-width=600}
Predictive Model Results
a <- 1:34
remove <- c (6, 18, 21:29, 31:33)
renderDT(
risk_map#data,
fillContainer = TRUE,
filter = "top",server = FALSE,
extensions = c('Buttons', 'Scroller'),
options = list(
dom = 'Blfrtip',
buttons = c('csv', 'excel', 'pdf'),
scrollY = '600px',
#scroller = TRUE,
fixedColumns = TRUE,
columnDefs = list(list(visible=FALSE, targets = a[! a %in% remove]))
# columnDefs = list(
# list(
# visible = FALSE,
# targets = c(6, 18, 21:29,31:33)
),
colnames = c(
"County Name" = "NAMELSAD",
"State" = "State",
"Dissimilarity Index 2019" = "dissim_19",
"2020 Population" = "Total_Pop20",
"% of Adults w/ Children" = "pct_adultsWchild_PH",
"Total CDBG Funding" = "total_amt_cdbg",
"Mean Poverty Index" = "mean_pov_idx",
"Mean Job Prxmity Index" = "mean_lbr_idx",
"Mean Transit Index" = "mean_trans_idx",
"More than 4 RECAPs" = "recap",
"AFH Submitter" = "AFH.Lead.Entity",
"CDBG Funding per Capita" = "CDBG_perCapita",
"Real Plan Outcome" = "real_outcome",
"Predicted Plan Outcome" = "predicted_outcome"
)
)
Generate Predicted Risk by County
Column {data-width=600}
Enter in Indicators to Predict Fair Housing Plan Outcome by County
# dissim_19 #input
# Total_Pop20 #input
# CDBG_perCapita
# pct_adultsWchild_PH #slider
# mean_pov_idx #slider
# mean_trans_idx #slider
# mean_lbr_idx #slider
# recap #yes or no multiple choice
sidebarPanel(
HTML("<h3>Enter in all input variables for your county to predict outcome of AFH<h4>"),
numericInput("dissim_19",
label = "White to Non-White Dissimilarity Index",
value = 34.58177),
numericInput("Total_Pop20",
label = "Total Population in 2020",
value = 2149031),
sliderInput("pct_adultsWchild_PH",
label = "Percent of Adults w at Least One Child in all of the County's Public Housing",
min = 0, max = 97, value = 1, step = 0.2),
numericInput("mean_pov_idx",
label = "Mean Poverty Index Score",
value = 35.00000),
numericInput("mean_trans_idx",
label = "Mean Transportation Index Score",
value = 39.000000),
numericInput("mean_lbr_idx",
label = "Mean LBR Index Score",
value = 1500000),
checkboxInput("recap", "Does the County have more than 4 census tracts designated as a RECAP? If Yes, click here", TRUE),
numericInput("CDBG_perCapita",
label = "Total CDBG Funding Amount per Capita",
value = 1500000),
actionButton("submitbutton", "Submit", class = "btn btn-primary")
)
mainPanel(
tags$label(h3('Status/Output')), # Status/Output Text Box
verbatimTextOutput('contents'),
tableOutput('tabledata') # Prediction results table
)
####################################
# Server #
####################################
server<- function(input, Output, session) {
# Input Data
datasetInput <- reactive({
df <- data.frame(
Name = c("White to Non-White Dissimilarity Index",
"Total Population in 2020",
"Percent of Adults w at Least One Child in all of the County's Public Housing",
"Mean Poverty Index Score",
"Mean Transportation Index Score",
"Mean LBR Index Score",
"Total CDBG Funding Amount per Capita"
),
Value = as.character(c(input$dissim_19,
input$Total_Pop20,
input$pct_adultsWchild_PH,
input$mean_pov_idx,
input$mean_trans_idx,
input$mean_lbr_idx,
input$CDBG_perCapita
)),
stringsAsFactors = FALSE)
Outcome <- 0
df <- rbind(df, Outcome)
input <- transpose(df)
write.table(input,"input.csv", sep=",", quote = FALSE, row.names = FALSE, col.names = FALSE)
test <- read.csv(paste("input", ".csv", sep=""), header = TRUE)
Output <- data.frame(Prediction=predict(model,test), round(predict(model,test,type="prob"), 3))
print(Output)
})
# Status/Output Text Box
Output$contents <- renderPrint({
if (input$submitbutton>0) {
isolate("Calculation complete.")
} else {
return("Server is ready for calculation.")
}
})
# Prediction results table
Output$tabledata <- renderTable({
if (input$submitbutton>0) {
isolate(datasetInput())
}
})
}
####################################
# Create the shiny app #
####################################
#shinyApp(ui = ui, server = server)
I'm trying to create and render an interactive formattable table in a shiny app.
Here is a sample dataframe:
tcharts <- data.frame(pgm = c(1,2,3,4,5,6,7,8),
horse = c("Cigar", "Funny Cide", "Animal Kingdom", "Blame", "Zenyatta", "New Years Day", "Northern Dancer", "Beautiful Pleasure"),
groundloss = c(55,70,85,42,90,45,53,50),
distanceRun = c(5050,5070,5085,5045,5090,5045,5053,5050),
ttl = c(50,70,85,42,90,45,53,50),
fps = c(52.3,51.8,51.9,52.0,53.6,52.9,53.7,53.1),
finishTime = c(52.3,51.8,51.9,52.0,53.6,52.9,53.7,53.1),
finish = c(4,7,1,2,5,6,3,8),
BL = c(0,1,2,6,2,9,6,8),
rnum = c(1,1,1,1,1,1,1,1),
sixteenth = c(330,330,330,330,330,330,330)
)
Working version
This version of the code, when list() is empty (use all variables in dataframe) produces a table as expected.
library(shiny)
library(formattable)
inputPanel(
selectInput("rnum", label = "Race Number:",
choices = c(1,2,3,4,5,6,7,8,9), selected = 1),
sliderInput("poc", label = "Point of Call:",
min = 330, max = 5280, value = 330, step = 330)
)
cdat <- reactive({
tcharts %>% filter(rnum %in% input$rnum) %>%
filter(Sixteenth %in% input$poc)
})
renderFormattable({
formattable(cdat(),list(
))
})
Error Version:
With this version, I get an ERROR: object pgm not found
library(shiny)
library(formattable)
inputPanel(
selectInput("rnum", label = "Race Number:",
choices = c(1,2,3,4,5,6,7,8,9), selected = 1),
sliderInput("poc", label = "Point of Call:",
min = 330, max = 5280, value = 330, step = 330)
)
cdat <- reactive({
tcharts %>% filter(rnum %in% input$rnum) %>%
filter(Sixteenth %in% input$poc)
})
renderFormattable({
formattable(cdat(),list(
pgm,
Horse
))
})
The error message leads me to believe I'm not specifying the variable correctly, but I'm not sure how to do it. I'v looked at several formattable / shiny SO questions and responses, but have not come up with the correct sytax.
I am trying to make a Shiny app where the user selects a few options and a network and data table will display based on the inputs. I have a diet study database and would like users to be able to specify the predator species they are interested in, the diet metric (weight, volumetric, etc) and the taxonomic level they want nodes identified to. The data table works fine (so I did not include the code) and updates based on the input but the network does not change, it only shows all of the data. When I run the code for generating the plot outside of Shiny it works fine. This is my first shiny attempt so any suggestions would be greatly appreciated.
library(dplyr)
library(igraph)
library(networkD3)
Diet <-data.frame(
Predator_Scientific_Name = rep("Acanthocybium solanderi", 10),
Class_Predator = rep("Actinopterygii", 10),
Order_Predator = rep("Perciformes", 10),
Family_Predator = rep("Scombridae", 10),
Genus_Predator = rep("Acanthocybium", 10),
Species_Predator = rep("solandri", 10),
Class_Prey = rep("Actinopterygii", 10),
Order_Prey = c( "Clupeiformes" , NA , "Perciformes", "Perciformes", "Perciformes", "Perciformes", "Perciformes", "Perciformes", "Tetraodontiformes", "Tetraodontiformes"),
Family_Prey = c("Clupeidae", NA, "Coryphaenidae", "Carangidae", "Scombridae","Echeneidae","Carangidae", "Scombridae", "Balistidae","Diodontidae"),
Genus_Prey = c("Sardinella", NA, "Coryphaena", "Decapterus", "Euthynnus", NA, NA, NA, "Balistes", "Diodon"),
Species_Prey = c("aurita" , "", "hippurus", "punctatus","alletteratus", "", "", "","capriscus", "spp." ),
Lowest_Taxonomic_Identification_Prey = c("Sardinella aurita","Actinopterygii","Coryphaena hippurus","Decapterus punctatus","Euthynnus alletteratus", "Echeneidae", "Carangidae","Scombridae","Balistes capriscus","Diodon spp."),
Frequency_of_Occurrence = c(2.8, 59.1, 1.4, 7.0, 1.4, 1.4, 15.5, 21.1, 2.8, 4.2), StringAsFactors = FALSE
)
pred.name <- unique(Diet$Predator_Scientific_Name)
prey.tax <- unique(Diet$Lowest_Taxonomic_Identification_Prey)
#Progress bar function
compute_data <- function(updateProgress = NULL) {
# Create 0-row data frame which will be used to store data
dat <- data.frame(x = numeric(0), y = numeric(0))
for (i in 1:10) {
Sys.sleep(0.25)
# Compute new row of data
new_row <- data.frame(x = rnorm(1), y = rnorm(1))
# If we were passed a progress update function, call it
if (is.function(updateProgress)) {
text <- paste0("x:", round(new_row$x, 2), " y:", round(new_row$y, 2))
updateProgress(detail = text)
}
# Add the new row of data
dat <- rbind(dat, new_row)
}
dat
}
####
# Define UI for application that draws a histogram
ui <- dashboardPage(
skin = "blue",
dashboardHeader(title = "Diet Database"),
dashboardSidebar(
sidebarMenu(
menuItem("Parameters",
tabName = "paramaters",
icon = shiny::icon("bar-chart")))
),
dashboardBody(
tabItems(
tabItem(
tabName = "paramaters",
fluidRow(
shiny::column(
width = 4,
shinydashboard::box(
title = "Predator",
status = "primary",
solidHeader = TRUE,
collapsible = TRUE,
width = NULL,
shiny::helpText("Select a predator to view its connections and prey items:"),
shiny::selectInput(
"pred",
shiny::h5("Predator Scientific Name:"),
c(NA,pred.name))),
shinydashboard::box(
title = "Prey",
status = "primary",
solidHeader = TRUE,
collapsible = TRUE,
width = NULL,
shiny::helpText("Select a prey taxa to view its connections and predators:"),
shiny::selectInput(
"prey",
shiny::h5("Prey Taxa:"),
c(NA,prey.tax))),
shinydashboard::box(
title = "Diet Metric",
status = "primary",
solidHeader = TRUE,
collapsible = TRUE,
width = NULL,
shiny::helpText("Select a diet metric to use:"),
shiny::selectInput(
"dietmetric",
shiny::h5("Diet Metric:"),
c("Frequency of Occurrence" = "Frequency_of_Occurrence",
"Wet Weight" = "Weight",
"Dry Weight" = "Dry_Weight",
"Volume" = "Volume",
"Index of Relative Importance" = "IRI",
"Index of Caloric Importance" = "ICI",
"Number" = "Number"))),
shinydashboard::box(
title = "Taxonomic Level",
status = "primary",
solidHeader = TRUE,
collapsible = TRUE,
width = NULL,
shiny::helpText("Select a taxonomic level of nodes:"),
shiny::selectInput(
"nodetax",
shiny::h5("Taxonomic Level:"),
c("Order" = "Order",
"Family" = "Family",
"Genus" = "Genus",
"Species" = "Species"))),
shinydashboard::box(
title = "Generate Network",
status = "primary",
solidHeader = T,
collapsible = T,
width = NULL,
actionButton("makenet", "Generate")
)
),
#Area for network to be displayed
shiny::column(
width = 8,
shinydashboard::box(
title = "Trophic Network",
status = "primary",
solidHeader = TRUE,
collapsible = FALSE,
width = NULL,
forceNetworkOutput("netplot")
)
)
))
)))
server <- function(input, output, session) {
network.data <- eventReactive(input$makenet, {
edgelist <- Diet %>% filter(Predator_Scientific_Name == input$pred|Lowest_Taxonomic_Identification_Prey == input$prey
) %>% select(
paste(input$nodetax, "Predator", sep = "_"),
Class_Predator,
paste(input$nodetax, "Prey", sep = "_"),
Class_Prey,
input$dietmetric
)
colnames(edgelist) <- c("SourceName",
"SourceClass",
"TargetName",
"TargetClass",
"Weight")
edgelist <- edgelist[complete.cases(edgelist),]
})
output$netplot <- renderForceNetwork( {
network.data()
ig <-igraph::simplify(igraph::graph_from_data_frame(edgelist[,c(1,3,5)], directed = TRUE))
SourceID <- TargetID <- c()
for (i in 1:nrow(edgelist)) {
SourceID[i] <- which(edgelist[i,1] == V(ig)$name)-1
TargetID[i] <- which(edgelist[i,3] == V(ig)$name)-1
}
#Create edgelist that contains source and target nodes and edge weights
edgeList <- cbind(edgelist, SourceID, TargetID)
nodeList <- data.frame(ID = c(0:(igraph::vcount(ig) - 1)),
nName = igraph::V(ig)$name)
#Determine and assign groups based on class
preddf <-
data.frame(SciName = edgelist[, 1], class = edgelist[, 2])
preydf <-
data.frame(SciName = edgelist[, 3], class = edgelist[, 4])
groupsdf <- rbind(preddf, preydf)
groupsdf <- groupsdf %>% mutate(SciName = as.character(SciName),
class = as.character(class))
nodeGroup <- c()
for (i in 1:nrow(nodeList)) {
index <- which(groupsdf[, 1] == nodeList$nName[i])
nodeGroup[i] <- groupsdf[index[1], 2]
}
nodeList <-
cbind(nodeList,
nodeGroup)
progress <- shiny::Progress$new()
progress$set(message = "Generating your network...", value = 0)
# Close the progress when this reactive exits (even if there's an error)
on.exit(progress$close())
# Create a callback function to update progress.
# Each time this is called:
# - If `value` is NULL, it will move the progress bar 1/5 of the remaining
# distance. If non-NULL, it will set the progress to that value.
# - It also accepts optional detail text.
updateProgress <- function(value = NULL, detail = NULL) {
if (is.null(value)) {
value <- progress$getValue()
value <- value + (progress$getMax() - value) / 5
}
progress$set(value = value, detail = detail)
}
# Compute the new data, and pass in the updateProgress function so
# that it can update the progress indicator.
compute_data(updateProgress)
networkD3::forceNetwork(
Links = edgeList,
# data frame that contains info about edges
Nodes = nodeList,
# data frame that contains info about nodes
Source = "SourceID",
# ID of source node
Target = "TargetID",
# ID of target node
Value = "Weight",
# value from the edge list (data frame) that will be used to value/weight relationship amongst nodes
NodeID = "nName",
# value from the node list (data frame) that contains node
Group = "nodeGroup",
# value from the node list (data frame) that contains value we want to use for node color
fontSize = 25,
opacity = 0.85,
zoom = TRUE,
# ability to zoom when click on the node
opacityNoHover = 0.4 # opacity of labels when static
)
})
}
# Run the application
shinyApp(ui = ui, server = server)
I am sharing my fixed code in case it helps someone in the future. I basically just changed the top of the server code.
network.data <- eventReactive(input$makenet, {
Diet %>% filter(Predator_Scientific_Name == input$pred|Lowest_Taxonomic_Identification_Prey == input$prey
) %>% select(
paste(input$nodetax, "Predator", sep = "_"),
Class_Predator,
paste(input$nodetax, "Prey", sep = "_"),
Class_Prey,
input$dietmetric
) %>% rename("SourceName" = paste(input$nodetax, "Predator", sep = "_"),
"SourceClass" = Class_Predator,
"TargetName" = paste(input$nodetax, "Prey", sep = "_"),
"TargetClass" = Class_Prey,
"Weight" = input$dietmetric) %>% na.omit()
})
output$netplot <- renderForceNetwork( {
edgelist <- network.data()
I'm re-posting this from scratch in hopes someone can get me through this learning opportunity.
I'm having trouble passing a variable from ui.R to server.R in the following Shiny app.
I'm also including global.R. One section of that file pings my cloud-based MySQL db. I didn't want to share the password for that on here; you can get the query results as CSV files (2 of them) here.
The problem is with Line 22 of server.R. With the code as-is (y = n.emp,), it works as expected. When I replace that with (y = input$quant,), the code breaks. The error is in that line. I have isolated that.
I've tried aes_string, as previously suggested. It did not work. (Maybe I didn't use it properly?)
Can anyone help me on this? Thanks!
server.R
# Define server logic required to draw a histogram
shinyServer(function(input, output) {
output$distPlot <- renderPlot({
### ----- MANIPULATE DATA -----
colors17 <- c("#a7dfb9","#d0a0d4","#fde096","#96bbf1","#ecb489","#6eceea","#eaa99e","#8adbd3","#ddb9f1","#9cc18d","#ebaec8","#dceeb6","#b6bee4","#c5c88f","#dfb89b","#e9cf9d","#c8c09a")
colors6 <- c("#74d5e0", "#e5b197", "#93c1ed", "#cfd6a0", "#dfb1d8", "#9adabe")
naics_jll$market <- factor(naics_jll$m.mkt,
levels = as.character(MKT))
naics_jll <- naics_jll %>%
filter(m.mkt %in% input$markets
# , (other), (filters), (here)
)
### ----- PLOT -----
g <- ggplot(naics_jll)
g + geom_bar(stat = "identity",
position = input$geom_bar_pos,
aes(x = m.mkt,
y = n.emp,
fill = c1.name),
color = "lightgrey") +
scale_fill_manual (values=colors17) +
# facet_wrap(~ m.mkt) +
labs( y = input$quant, title = "Market Structure", subtitle = "by market & industry") +
theme(strip.text.x = element_text(size = 8),
axis.text.x = element_text(angle=90, size=6))
})
})
ui.R
# Define UI for application that draws a histogram
shinyUI(fluidPage(
title = "Company Data Explorer",
plotOutput('distPlot'),
hr(),
fluidRow(
column(3,
radioButtons("geom_bar_pos", "",
c("Stacked Bars" = "stack",
"Grouped Bars" = "dodge"),selected = "dodge")
),
column(4, offset = 1,
checkboxGroupInput("markets", "Include Markets:",
c("Boston" = "BOS",
"NYC" = "NYC",
"Chicago" = "CHI",
"San Francisco" = "SF",
"Los Angeles" = "LA",
"Washington, DC" = "DC"),
selected = c("BOS","NYC","CHI","SF","LA","DC"))),
column(4,
selectInput('quant', 'Y-Values', names(y_vals),names(y_vals)[[4]]))
)
))
global.R
library(shiny)
library(RNeo4j)
library(tidyverse)
library(stringr)
library(ggplot2)
### GET DATA
## MySQL SERVER CONNECT
con <- dbConnect(MySQL(),
user = 'shiny_apps',
password = '****',
host = 'mysql.mvabl.com',
dbname='sandbox191')
qmain <- dbSendQuery(con, "SELECT * FROM naics_jll;")
naics_jll <- as.data.frame(dbFetch(qmain,n=-1),na.rm=TRUE)
dbHasCompleted(qmain)
dbClearResult(qmain)
dbDisconnect(con)
## LOAD CSV
naics_jll <- select(naics_jll,-n.msa_naics,-c1.id,-q.level,-q.qtr,-q.nbrhd,-N.BldgClass)
y_vals <- subset(naics_jll,select = which(sapply(naics_jll,is.numeric)))
dropdown <- c("m.mkt","c1.name","q.nbrhd")
### "LEVELS" VARIABLES (currently unused)
IND <- naics_jll %>% distinct(c1.name)
MKT <- naics_jll %>% distinct(m.mkt)
I finally solved it, with help from Joe Cheng's gist. I needed to define my data source as reactive. Guess that's a new subject to read up on!!