I am trying to build a selector for a datatable object in my flexmarkdown sheet.
So this is my current (example) layout and I'm trying to build a reactive selector that takes the mineral type input on the left side and then re-renders
the entire table to only select for "Rock Type = Type 1" in this case.
Full source #pastebin here: Link
My current selector:
```{r}
selectInput("input_type","Mineral Type:", data$`Rock Type`)
```
I'm been able to achieve this by doing the below but I'd also like to build in a selection for all/no groupings.
```{r}
dataInput <- reactive({
subset(data,data$`Rock Type` == input$input_type)
})
renderDataTable(dataInput())
```
You can add an All option to your selectInput, that you check in the reactive:
```{r}
selectInput("input_type","Mineral Type:", c("All", unique(data$`Rock Type`))
```
```{r}
dataInput <- reactive({
if(input$input_type=="All")
data
else
subset(data,`Rock Type` == input$input_type)
})
renderDataTable(dataInput())
```
Related
I have a r leaflet map that has multiple layers and each layer can be checked or unchecked. I am trying to find a way to have a select all/deselect all option.
Below is my code where the overlays are reactive groups.
df() is a reactive dataframe
myLocation() is a reactive location (long,lat)
So in the map in the upper right hand corner is where I want a select all/ deselect all option
groups <- reactive({as.character(unique(df()$Folder))})
groupColors <- reactive({
colorFactor(palette = rainbow(length(groups())),
domain = df()$Folder)
})
output$mymap <- renderLeaflet({
leaflet() %>%
addTiles() %>%
leaflet::addMarkers(lng=c(myLocation()[1]), lat=c(myLocation()[2]),
popup = paste("Lat/Long: ",myLocation()[2],"/",myLocation()[1]),
popupOptions = popupOptions(maxWidth = 1000, closeOnClick = TRUE))
%>%
############more code here
#this section is where a select all/ deselect option has to be placed
addLayersControl(overlayGroups=groups(),options =
layersControlOptions(collapsed = TRUE))
})
Following shiny tutorial... try using leafletProxy to modify your existing map and use the hideGroup() function from leaflet to add/remove the entire group.
I have a Rmarkdown document with an embedded shiny application (runtime: shiny) which I'd like to upload to shinyapps.io (eventually). When I build the document locally, it fails to completely build, as in the page stops halfway through the document. I've confirmed that if I remove some large leaflet objects in the middle of the document then the build finishes.
I'm working on making the leaflet objects smaller, but I've seen that there is a memory limit on Shiny apps that can be reconfigured (options(shiny.maxRequestSize=30*1024^2) for 30 MB). Supposedly this is supposed to go in the server section of an app, but if the entire document is an app, does this go in the yaml, or in a setup chunk, or somewhere else?
I was able to make an MWE that illustrates my basic environment, though it does not reproduce the error. The maps chunk shows a leaflet map of census tracts for each of the 50 states and DC, and then there's a true shiny app following.
---
title: "Test RMD"
output: html_document
runtime: shiny
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
library(leaflet)
library(shiny)
library(tigris)
library(htmltools)
library(RColorBrewer)
options(shiny.maxRequestSize=30*1024^2)
```
# leaflet maps
```{r maps, echo=T,results='asis'}
us_states <- unique(fips_codes$state)[1:51] # for small, set to 2
createMaps <- function(state){
stmap <- tracts(state, cb = TRUE)
leaflet(stmap) %>% addTiles() %>% addPolygons()
}
htmltools::tagList(lapply(us_states, function(x) createMaps(x) ))
```
# Shiny application
```{r tabsets, echo=FALSE}
shinyApp(
ui = bootstrapPage(
tags$style(type = "text/css", "html, body {width:100%;height:100%}"),
leafletOutput("map", width = "100%", height = "100%"),
absolutePanel(top = 10, right = 10,
sliderInput("range", "Magnitudes", min(quakes$mag), max(quakes$mag),
value = range(quakes$mag), step = 0.1
),
selectInput("colors", "Color Scheme",
rownames(subset(brewer.pal.info, category %in% c("seq", "div")))
),
checkboxInput("legend", "Show legend", TRUE)
)
),
server = function(input, output, session) {
# Reactive expression for the data subsetted to what the user selected
filteredData <- reactive({
quakes[quakes$mag >= input$range[1] & quakes$mag <= input$range[2],]
})
# This reactive expression represents the palette function,
# which changes as the user makes selections in UI.
colorpal <- reactive({
colorNumeric(input$colors, quakes$mag)
})
output$map <- renderLeaflet({
# Use leaflet() here, and only include aspects of the map that
# won't need to change dynamically (at least, not unless the
# entire map is being torn down and recreated).
leaflet(quakes) %>% addTiles() %>%
fitBounds(~min(long), ~min(lat), ~max(long), ~max(lat))
})
# Incremental changes to the map (in this case, replacing the
# circles when a new color is chosen) should be performed in
# an observer. Each independent set of things that can change
# should be managed in its own observer.
observe({
pal <- colorpal()
leafletProxy("map", data = filteredData()) %>%
clearShapes() %>%
addCircles(radius = ~10^mag/10, weight = 1, color = "#777777",
fillColor = ~pal(mag), fillOpacity = 0.7, popup = ~paste(mag)
)
})
# Use a separate observer to recreate the legend as needed.
observe({
proxy <- leafletProxy("map", data = quakes)
# Remove any existing legend, and only if the legend is
# enabled, create a new one.
proxy %>% clearControls()
if (input$legend) {
pal <- colorpal()
proxy %>% addLegend(position = "bottomright",
pal = pal, values = ~mag
)
}
})
}
)
```
I guess my main question is if the options() call is going in a place where Shiny can see it. It's also possible that if I made the application itself bigger that it would cause problems; I can try to get to that this evening.
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.
I am developing an R Markdown Shiny document to:
Subset a data frame to include the "date" column and some numeric data columns. The way the shiny user input is set up, you select radio buttons for the data columns to include, then hit the "Subset Data" button to create d() - NO PROBLEM:)
Generate a list of plots (plotList), one for each numeric data column (plotted against the date column). I am using the openair package timePlot function to generate the plots, and lapply to generate the list of plot objects (plotList) - NO PROBLEM:)
use renderPlot to output all the plots in plotList to the R Markdown document - PROBLEM:(
I know there have been similar questions (e.g https://gist.github.com/wch/5436415/, Reactivity in R shiny with toy example, and dynamically add plots to web page using shiny), and please believe me I have tried and tried (e.g. using a for loop in stead of lapply-not my preference, but if it worked then who cares; adding local() and/or observe(); etc). No matter what I do I can't get it to to work. I am new to R Markdown and to Shiny, I just can't figure this out - please help!
Here is a reproducible example (to be run as an R markdown shiny document).
First the chunk that creates a reactive dataset d():
```{r reactive-dataset, echo=FALSE,message=FALSE}
library(openair)
library(dplyr)
data<-mydata[1:50,]
print(tbl_df(data))
inputPanel(
checkboxGroupInput(inputId="p",
label="select pollutants to plot",
choices=names(data)[-1]
),
actionButton(inputId="import",
label="Subset Data")
)
d<-eventReactive(input$import,{
d<-data %>% select(date,one_of(input$p))
})
renderPrint({tbl_df(d())})
```
Now the second chunk, to create plotList and output it (PART THAT DOESN'T WORK):
Attempt 1: only last plot is displayed
```{r plot,echo=FALSE,message=FALSE}
renderPlot({
i<-names(d())[-1]
tp<-function(x){
p<-timePlot(d(),
pollutant=print(x),
main="Minute Validation",
ylab="Minute Conc. (ug/m3 or ppb)",
key=T)
p$plot
}
lapply(i,tp)
})
```
Attempt 2 (based on Reactivity in R shiny with toy example). No plots are displayed
```{r plot,echo=FALSE,message=FALSE}
plotList<-reactive({
i<-names(d())[-1]
tp<-function(x){
p<-timePlot(d(),
pollutant=print(x),
main="Minute Validation",
ylab="Minute Conc. (ug/m3 or ppb)",
key=T)
p$plot
}
lapply(i,tp)
})
observe({
for (j in 1:length(plotList())){
local({
my_j<-j
renderPlot({plotList()[[my_j]]})
})#end local
} #end for loop
}) #end observe
```
I have fiddled with this endlessly, referring the to similar questions that I have linked to above.
[New answer]
I finally got this worked out. The key is to exactly follow the example in the third link of your post, using renderUI first!
```{r plot,echo=FALSE,message=FALSE}
tp_list <- reactive({
i<-names(d())[-1]
tp<-function(x){
p<-timePlot(d(),
pollutant=print(x),
main="Minute Validation",
ylab="Minute Conc. (ug/m3 or ppb)",
key=T)
p$plot
}
lapply(i, tp)
})
renderUI({
plot_output_list <- lapply(1:length(tp_list()), function(i) {
plotname <- paste("plot", i, sep="")
plotOutput(plotname)
})
do.call(tagList, plot_output_list)
})
observe({
for (i in 1:length(tp_list())) {
local({
my_i <- i
plotname <- paste("plot", my_i, sep="")
output[[plotname]] <- renderPlot({
tp_list()[[my_i]]
})
})
}
})
```
[Original answer based on lattice panels]
This is not exactly what you want, but I got all the plots displayed in one plot.
```{r plot,echo=FALSE,message=FALSE}
renderPlot({
i<-names(d())[-1]
tp<-function(x){
p<-timePlot(d(),
pollutant=print(x),
main="Minute Validation",
ylab="Minute Conc. (ug/m3 or ppb)",
key=T)
p$plot
}
tp(i)
})
```
Hi having a couple of problems
a) creating the correct text to pass variables to ggvis - not even sure aes_string is applicable
b) The plot propagates in browser rather than rendering in the rmarkdown document
Here is an example
---
title: "Untitled"
author: "pssguy"
date: "Sunday, August 24, 2014"
output: html_document
runtime: shiny
---
```{r, echo = FALSE, message=FALSE}
library(ggplot2)
library(ggvis)
library(dplyr)
selectInput("category3", "Choose Dataset:", c("mpg", "disp", "qsec"))
# ggplot renders correctly within renderPlot
renderPlot({
ggplot(mtcars,aes_string(input$category3,"disp"))+geom_point()
})
# ggvis works within document with hard coded info
mtcars %>% ggvis(~wt,~disp)
mtcars %>% ggvis(aes_string(paste("~",input$category3,","),"~disp"))
#Operation not allowed without an active reactive context. (You tried to do something that can only be done from inside a reactive expression or observer.)
# This needs correcting anyways
renderPlot({
mtcars %>% ggvis(aes_string(paste("~",input$category3,","),"~disp"))
})
# <text>:1:7: unexpected ',' 1: ~ mpg ,
# even if the above is corrected the plot opens in a browser rather than the document
renderPlot({
mtcars %>% ggvis(~wt,~disp)
})
```
TIA
This should do it:
---
title: "Untitled"
output: html_document
runtime: shiny
---
```{r, echo = FALSE, message=FALSE}
library(ggplot2)
library(ggvis)
library(dplyr)
selectInput("category3", "Choose Dataset:", c("mpg", "disp", "qsec"))
# ggplot renders correctly within renderPlot
renderPlot({
print(input$category3)
ggplot(mtcars,aes_string(input$category3,"disp"))+geom_point()
})
# ggvis with dynamically changing columns
reactive({
if (!is.null(input$category3))
col <- input$category3
else
col <- "mpg"
mtcars %>% ggvis(prop("x", as.name(col)), ~disp)
}) %>% bind_shiny('foo')
ggvisOutput('foo')
```
It's a little complicated because you need a NULL check for the category, and you need to explicitly tell knitr to put a ggvis output on the page.