I created a simple plot that when the user clicks on a point it generates another plot on a second tab, Page_2 -- is it possible to add some custom JS so that when the user clicks on the point they are automatically re-routed to the Page_2 tab?
library(shiny)
library(plotly)
library(tidyverse)
# ui with two panes
# when you click on the outlier in the first plot
# you are routed to the second "point explorer" page
ui <- navbarPage("Plotly On Click Switch Pane",
tabPanel("Page_1",
mainPanel(plotlyOutput("plot"),
tableOutput("text"))),
tabPanel("Page_2",
mainPanel(plotlyOutput("ind_plot"))
))
server <- function(input, output) {
# plot on first page
output$plot <- renderPlotly({
ggplotly(source = "sub_iris",
ggplot(iris, aes(x = Species, y = Petal.Width)) +
geom_boxplot()
)
})
# create reactive for subset plot on second tab
s <- reactive({ event_data("plotly_click", source = "sub_iris") })
# plot text on first page (test)
output$text <- renderTable(event_data("plotly_click", source = "sub_iris"))
# this is the correct plot, but I want to re-route the user here when they click on a point
output$ind_plot <- renderPlotly({
iris_ind <- subset(iris)[subset(s(), curveNumber == 0)$pointNumber + 1,]
ggplotly(
ggplot(iris_ind, aes(x = Species, y = Sepal.Length)) +
geom_bar(stat = "identity")
)
})
}
# Run the application
shinyApp(ui = ui, server = server)
You can use updateNavbarPage after providing your navbarPage with an id:
library(shiny)
library(plotly)
library(tidyverse)
# ui with two panes
# when you click on the outlier in the first plot
# you are routed to the second "point explorer" page
ui <- navbarPage("Plotly On Click Switch Pane", id = "navbarID",
tabPanel("Page_1",
mainPanel(plotlyOutput("plot"),
tableOutput("text"))),
tabPanel("Page_2",
mainPanel(plotlyOutput("ind_plot"))
))
server <- function(input, output, session) {
# plot on first page
output$plot <- renderPlotly({
ggplotly(source = "sub_iris",
ggplot(iris, aes(x = Species, y = Petal.Width)) +
geom_boxplot()
)
})
# create reactive for subset plot on second tab
s <- reactive({
event_data("plotly_click", source = "sub_iris")
})
observeEvent(s(), {
updateNavbarPage(session, inputId = "navbarID", selected = "Page_2")
})
# plot text on first page (test)
output$text <- renderTable(req(s()))
# this is the correct plot, but I want to re-route the user here when they click on a point
output$ind_plot <- renderPlotly({
req(s())
iris_ind <- subset(iris)[subset(s(), curveNumber == 0)$pointNumber + 1,]
ggplotly(
ggplot(iris_ind, aes(x = Species, y = Sepal.Length)) +
geom_bar(stat = "identity")
)
})
}
# Run the application
shinyApp(ui = ui, server = server)
Related
I want to hide a selectInput so it doesnt let people try and use it before the data has loaded.
Snippet of UI code.
ui <- dashboardPage(
dashboardHeader(title = "TCS Adverse Event Search Tool"),
dashboardSidebar(
sidebarMenu(
shinycssloaders::withSpinner(
selectInput("ingredients",
label = "Select one or more Active Ingredients:",
choices = NULL,
multi=TRUE)
),
In my server function I have this:
server <- function(input, output, session) {
# get main data frame
ingredients_df <- reactive({
ingredients_df <- read.csv(file="/projects/other/pv_compliance/active_ingredients.csv")
print(paste(nrow(ingredients_df)," active ingredient rows returned"))
return(ingredients_df)
})
cases_df <- reactive({
cases_df <- read.csv(file="/projects/other/pv_compliance/adverse_events.csv")
print(paste(nrow(cases_df)," case rows returned"))
return(cases_df)
})
observeEvent(ingredients_df(), {
updateSelectInput(session,
"ingredients",
choices = ingredients_df()$PRIMARY_SUSPECT_KEY_INGREDIENT,
selected = NULL
)
})
Two things are happening...
the set of widgets now appear about halfway down the sidebar and not the top
the css loader does not display when the updateSelectInput is getting the data
I am trying filter my data using the dplyr package inside the reactive function in Shiny, but nothing is being displayed in the output. The data is supposed to be filtered by levels of the variable "Country".
Here is the code I have used and the dataframe
datos<-data.frame(time=c(rep(c(2001, 2002),3)), values=c(100,200,300,600,700,800), country=c(rep("Uruguay",2),rep("France",2),rep("United States",2)))
ui <- fluidPage(
selectInput(inputId ="pais", label="Choose a country",
choices =levels(datos$country), selected = "Uruguay"),
plotOutput(outputId ="barplot")
)
server <- function(input, output) {
datos3 <- reactive({
datos%>%
filter(country=="input$pais")
})
output$barplot<-renderPlot({
ggplot(datos3(),aes(x=time,y=values))+geom_bar(stat="Identity")
})
}
shinyApp(ui = ui, server = server)
I am supposed to obtain the values for the selected country, by time period.
You didn't need the quotation marks on "input$pais".
Here is the code with that and the extra + in the ggplot section removed.
library(shiny)
library(tidyverse)
datos<-data.frame(time=c(rep(c(2001, 2002),3)), values=c(100,200,300,600,700,800), country=c(rep("Uruguay",2),rep("France",2),rep("United States",2)))
ui <- fluidPage(
selectInput(inputId ="pais", label="Choose a country",
choices =levels(datos$country), selected = "Uruguay"),
plotOutput(outputId ="barplot")
)
server <- function(input, output) {
datos3 <- reactive({
datos%>%
filter(country==input$pais) #this bit has been changed
})
output$barplot<-renderPlot({
ggplot(datos3(),aes(x=time,y=values))+geom_bar(stat="Identity")
})
}
shinyApp(ui = ui, server = server)
I'm working on leaflet with shiny. The tools is basic, i have a map with some markers (coming from a table with LONG and LAT).
What I want to do is to open a table or a graph when i click on the marker.
Is there a simple way to do it?
Do you have a really simple example: you have a maker on a map, you click on the marker, and there is a plot or a table or jpeg that s opening?
Here is another example, taken from here and a little bit adapted. When you click on a marker, the table below will change accordingly.
Apart from that, a good resource is this manual here:
https://rstudio.github.io/leaflet/shiny.html
library(leaflet)
library(shiny)
myData <- data.frame(
lat = c(54.406486, 53.406486),
lng = c(-2.925284, -1.925284),
id = c(1,2)
)
ui <- fluidPage(
leafletOutput("map"),
p(),
tableOutput("myTable")
)
server <- shinyServer(function(input, output) {
data <- reactiveValues(clickedMarker=NULL)
# produce the basic leaflet map with single marker
output$map <- renderLeaflet(
leaflet() %>%
addProviderTiles("CartoDB.Positron") %>%
addCircleMarkers(lat = myData$lat, lng = myData$lng, layerId = myData$id)
)
# observe the marker click info and print to console when it is changed.
observeEvent(input$map_marker_click,{
print("observed map_marker_click")
data$clickedMarker <- input$map_marker_click
print(data$clickedMarker)
output$myTable <- renderTable({
return(
subset(myData,id == data$clickedMarker$id)
)
})
})
})
shinyApp(ui, server)
There is a leaflet example file here:
https://github.com/rstudio/shiny-examples/blob/ca20e6b3a6be9d5e75cfb2fcba12dd02384d49e3/063-superzip-example/server.R
# When map is clicked, show a popup with city info
observe({
leafletProxy("map") %>% clearPopups()
event <- input$map_shape_click
if (is.null(event))
return()
isolate({
showZipcodePopup(event$id, event$lat, event$lng)
})
})
Online demo (see what happens when you click on a bubble):
http://shiny.rstudio.com/gallery/superzip-example.html
On the client side, whenever a click on a marker takes place, JavaScript takes this event and communicates with the Shiny server-side which can handle it as input$map_shape_click.
How can I get the list of choices in a SelectInpute?
ui.R
selectInput(inputId = "select_gender",
label = "Gender",
choices = c("Male","Female"),
width = 150
)
server.R
# Something like...
genders <- input$select_gender["choices"]
# So that the gender would be:
> genders
[1] Male Female
From the scoping rules of Shiny:
Objects defined in global.R are similar to those defined in app.R outside of the server function definition, with one important difference: they are also visible to the code in the ui object. This is because they are loaded into the global environment of the R session; all R code in a Shiny app is run in the global environment or a child of it.
However, this doesn't mean that objects defined in the app.R can't be used on both the UI and Server side, they just belong to a different environment.
For example:
library("shiny")
library("pryr")
# or in global.R
genders <- c("Male", "Female")
gen_env <- where("genders")
par_env <- parent.env(gen_env)
ui <- fluidPage(
selectInput("shiny_gender", "Select Gender", choices = genders),
verbatimTextOutput("selected_gender_index"),
p("The `genders` object belongs to the environment:"),
verbatimTextOutput("gen_env_print"),
p("Which is the child of the environment:"),
verbatimTextOutput("par_env_print")
)
server <- function(input, output) {
output$selected_gender_index <- renderPrint({
# use the 'genders' vector on the server side as well
which(genders %in% input$shiny_gender)
})
output$gen_env_print <- renderPrint(gen_env)
output$par_env_print <- renderPrint(par_env)
}
shinyApp(ui = ui, server = server)
I've looked for get choices of selectinput but without recompute the choices. For example if the datas come from database, or file or other source.
And I didn't get answer. (I get this question but not the solution for me).
Here is ma solution which also could set the selectinput from the server:
set the choices list in a reactive function
build the selectinput in the server side (with the choices list reactive function)
set and get the selectinput in the server side
Here is the code
options(encoding = "UTF-8")
library("shiny")
library("pryr")
ui <- fluidPage(
uiOutput("shiny_gender.UI"),
verbatimTextOutput("selected_gender_index"),
p("The `genders` object belongs to the environment:"),
verbatimTextOutput("gen_env_print"),
p("Which is the child of the environment:"),
verbatimTextOutput("par_env_print"),
p(""),
textInput("set_input_txt","Set the car in letter (for example `Datsun 710`)",
#" Set the Select Input Male / Female ",
""),
actionButton("submit","submit")
)
server <- function(input, output, session) {
observeEvent(
c(input$submit),
{
if (input$submit>0) {
updateSelectInput(session, "shiny_gender",
# server = TRUE, if updateSelectizeInput
choices =shiny_gender.list(),
selected = input$set_input_txt
)
}
}
)
shiny_gender.list <- reactive ({
#c("Male", "Female")
rownames(mtcars)
})
output$shiny_gender.UI <- renderUI({
selectInput( "shiny_gender",
label="Select car",#"Select Gender",
choices =shiny_gender.list()
)
})
output$selected_gender_index <- renderPrint({
which(shiny_gender.list() %in% input$shiny_gender)
})
output$gen_env_print <- renderPrint(where("shiny_gender.list"))
output$par_env_print <- renderPrint(parent.env( where("shiny_gender.list")))
}
shinyApp(ui = ui, server = server)
I am new to Shiny and am trying to add a chord diagram to a shiny server. When I hit the runApp button in RStudio I get the application to run and it generates the UI, but then closes down immediately and I get the following error in the RConsole window: Error in (structure(function (input, output) :
could not find function "renderplot".
Unfortunately, I cannot attach the data as it is proprietary, but I am just creating an adjacency matrix in order to generate the chord plot. The Chord plot works fine outside Shiny. Thanks in advance!
My UI and Server code is below:
library(shiny)
# Starting line
shinyUI(fluidPage(
# Application title
titlePanel("Chord Chart"),
# Sidebar
sidebarLayout(
sidebarPanel(
#Data selection for Chord Chart
selectInput("data","Select a Dataset:",
c("Marine"))),
#The plot created in server.R is displayed
mainPanel(
plotOutput("plot")
)))
)
library(circlize)
library(dplyr)
library(reshape2)
library(manipulate)
library(shiny)
# read marine summaries
marine <- readfile("C:/Personal/R/MarineDataSummary.csv")
# group and summarize by O-D
marine.sum <- marine %>%group_by(Handling_Port, OD_Port_Country) %>%
summarise(tons <-sum(tonnes)) # prepare pivot table
marine.sum1 <- acast(marine.sum, Handling_Port~OD_Port_Country, value.tons="z") # reshape matrix
marine.sum1[is.na(marine.sum1)] <- 0 # set NA to zero
#initialization of server.R
shinyServer(function(input, output) {
output$plot <- renderplot({
c <- chordDiagram(marine.sum1,annotationTrack="grid",preAllocateTracks=list(track.height = 0.3))
##change axis
c <- c + circos.trackPlotRegion(track.index=1, panel.fun=function(x,y) {
xlim = get.cell.meta.data("xlim")
ylim = get.cell.meta.data("ylim")
sector.name=get.cell.meta.data("sector.index")
circos.text(mean(xlim), ylim[1], sector.name,facing="clockwise",
niceFacing=TRUE,adj=c(0,0.4), cex = 0.4)},bg.border=NA)
print(c)
})
})