how to select data based on a first selection - shiny app - shiny

I am new to using Shiny, I have read the tutorials, and a few questions on stacked overflow, but I think I"m still missing some key concept.
Basically I want users to first select a dataset.
Then based on that dataset they can select an OTU of interest.
Then I will display a plot and maybe a table.
I have the syntax for selecting the dataset correct, but how do I generate the choices of OTUs to select based on that ?
Any help appreciated.
thanks
ui <- fluidPage(
# Make a title to display in the app
titlePanel(" Exploring the Effect of Metarhizium on the Soil and Root Microbiome "),
# Make the Sidebar layout
sidebarLayout(
# Put in the sidebar all the input functions
sidebarPanel(
# drop down menu to select the dataset of interest
selectInput('dataset', 'dataset', names(abundance_tables)),
# drop down menu to select the OTU of interest
uiOutput("otu"),
#
br(),
# Add comment
p("For details on OTU identification please refer to the original publications")
),
# Put in the main panel of the layout the output functions
mainPanel(
plotOutput('plot')
# ,dataTableOutput("anova.tab")
)
)
)
server <- function(input, output){
# Return the requested dataset ----
datasetInput <- reactive({
switch(input$dataset)
})
#
dataset <- datasetInput()
# output otus to choose basaed on dataset selection
output$otu <- renderUI({
selectInput(inputId = "otu", label = "otu",
choices = colnames(dataset))
})
output$plot <- renderPlot({
#
dataset <- datasetInput()
otu <- input$otu
#dataset<-abundance_tables[[1]]
## melt and add sample metadata
df_annot<-merge(dataset,sample_metadata,by="row.names",all.x=T)
rownames(df_annot)<-df_annot[,1]
df_annot<-df_annot[,-1]
#
dfM<-melt(df_annot,id.vars = c("Location","Bean","Fungi","Insect"),value.name="abund")
# renaming Fungi level to metarhizium
levels(dfM$Fungi)<-c("Metarhizium","No Meta")
#
ggplot(subset(dfM, variable==otu),
aes(x=Insect,y=abund,fill=Fungi))+geom_boxplot()+facet_wrap(~Location,scales="free_y" )+
guides(fill=guide_legend("Metarhizium")) +
ggtitle(otu)
})
}
##
shinyApp(ui=ui,server=server)
Okay, I have made some fixes after some answers, but am now getting the following error.
Listening on http://127.0.0.1:5684
Warning: Error in .getReactiveEnvironment()$currentContext: 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.)
Stack trace (innermost first):
41: .getReactiveEnvironment()$currentContext
40: .dependents$register
39: datasetInput
38: server [/Users/alisonwaller/Documents/Professional/Brock/Bidochka_Microbiome/shiny/Barelli_shiny.R#68]
1: runApp
Error in .getReactiveEnvironment()$currentContext() :
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.)

Yes you are really close. Just replace this line:
selectInput('otu', 'otu', uiOutput("otu")),
with this: uiOutput("otu"),
There's no need for SelectInput() here since that is in the renderUI in the server function.

Related

Problem using if and Else to render text in R shiny

I am trying to set up a shiny app which allows individuals to select an option and then with that option a specific text appears if they select the other option different text appears.
Currently i am getting an error, i have tried to use the if else, I am new to shiny and fairly new to R so am struggling with the code.
I have tried playing about with using a reactive x but couldn't get it to work either potentially because this is not numeric?
# Sidebar with a select input for number of bins
sidebarLayout(
sidebarPanel(
selectInput(inputId = "Options",
label = "Option",
choices = c("Option 1","Option 2"))
),
# Show a text output
mainPanel(
textOutput(outputId = "ParticpantInformation1"),
textOutput(outputId = "ParticpantInformation2")
)),
# Define server logic required to rendertext
server <- function(input, output) {
if (input$Options=="Option 1") output$ParticpantInformation1 <- renderText("Option 1")
else output$ParticpantInformation2 <-renderText("Option 2")
I am hoping for it to render either one set of text or the other onto the main panel of the app
Currently i get an Error - "cannot coerce type 'closure' to vector of type 'character' "
You don't need that if(). You can directly refer to the user selection like this:
library(shiny)
ui <- fluidPage(
# Sidebar with a select input for number of bins
sidebarLayout(
sidebarPanel(
selectInput(inputId = "Options",
label = "Option",
choices = list("Option 1" = "My option 1 text", "Option 2" = "My option 2 text"))
),
# Show a text output
mainPanel(
textOutput(outputId = "ParticpantInformation")
))
)
server <- function(input, output, session) {
output$ParticpantInformation <- renderText({input$Options})
}
shinyApp(ui = ui, server = server)
For an alternative please see ?conditionalPanel, but for this case it's unnecessary complex.

How do I write to a bigquery table from shiny?

I'm trying to write a shiny app that takes a file as an input and uploads the data in that file to a bigquery table where some other stuff will go on. Everything appears to be working fine in terms of getting the data into my app, but when I try to upload the data to bigquery, nothing happens. No error messages, just nothing.
I can run the code on its own and it executes just fine. I'm having a little trouble figuring out how to create a reproducible example because you can't write to a public dataset, but I've included my code below.
Additional info:
working directory contains my .httr-oauth file
data is visible in my shiny app
Please let me know if there's something I can add to make this question easier to answer. Thanks.
############# UI ############
#
library(shiny)
shinyUI(fluidPage(
# Application title
titlePanel("Upload"),
# Sidebar with a slider input for number of bins
sidebarLayout(
sidebarPanel(
fileInput('list', 'Choose file to upload',
accept = c(
'text/csv',
'text/comma-separated-values',
'.csv'
)),
tags$hr(),
textInput('sql', 'Or give a query to get the customer_ids you want'),
tags$hr(),
actionButton('go', 'Go')
),
# Show a plot of the generated distribution
mainPanel(
tableOutput('log')
)
)
))
############# server ##############
### setting up the environment
library(shiny)
library(data.table)
library(bigrquery)
### setting up the constants
project <- 'xxxxxxx'
dest_dataset <- 'temp'
dest_table <- 'custs_hash'
cd <- 'CREATE_IF_NEEDED'
wd <- 'WRITE_TRUNCATE'
options(shiny.maxRequestSize = 100*1024^2)
shinyServer(function(input, output) {
logs <- eventReactive(input$go, {
inFile <- input$list
dat <- fread(inFile$datapath)
dat <- head(dat)
return(list(dat = dat))
})
upload <- eventReactive(input$go, {
data <- dat()$dat
ins <- insert_upload_job(project, dataset = dest_dataset, table = dest_table, values = data,
create_disposition = cd, write_disposition = wd)
return(list(ins = ins))
})
output$log <- renderTable(logs()$dat)
})
An eventReactive returns a reactive expression object. Like other reactive objects, you need to expressly call it like a function. Otherwise it won't run by itself.
So in your case, you have upload <- eventReactive(...), then you need to call it using upload().

Click on marker to open plot / data table

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.

Use Shiny to display bar graph by state

I'm trying to use shiny to create a bar graph for a state that is selected via drop-down box. I'm quite new to R and I've tried a variety of examples to no avail. I have three variables (state, claim #, total $) and for each state there are five values. So something like this:
state <- c("PA", "TX", "NY")
claim_num <- c(1:15)
total <- sample(1000:5000, 15)
df <- (state, claim_num, total)
I want to have something similar to https://beta.rstudioconnect.com/jjallaire/shiny-embedding/#inline-app but I don't know if I can format my data in that was since I would have a lot of NAs.
Do you mean something like this (you can download and run the example)?
library(shiny)
ui <- shinyUI(
fluidPage(
titlePanel("Sample Shiny App"),
sidebarLayout(
sidebarPanel(
uiOutput("stateInput")
),
mainPanel(
plotOutput("statePlot")
)
)
))
server <- shinyServer(function(input, output) {
state <- sample(state.abb, 3, replace = FALSE)
total <- sample(1000:5000, 15)
claimNumber <- 1:15
data <- data.frame(state, total, claimNumber)
output$stateInput <- renderUI({
selectInput(
inputId = "state",
label = "Select a State:",
choices = levels(data$state)
)
})
output$statePlot <- renderPlot({
hist(data$total[data$state == input$state])
})
})
shinyApp(ui = ui, server = server)
What we're doing is taking the list of unique states available in our data frame and passing those to our selectInput that renders as a dropdown in the UI. From here, we can access whatever value the user has selected through the input$state object. More generally, we can access inputs based on whatever we define the inputId to be (in this particular case, we call it state).
Having grabbed the user input, we can then subset the data frame to only return values that correspond to the user-defined state and, in this case, pass those totals values to a plot that we render as output.

Shiny application -- how to suppress function and rendering on launch?

I developed a Shiny App with RStudio that takes input, performs a search of a look-up table, and then returns a value. The search is not supposed to be performed until the user hits the submit button. However, upon launch, the App automatically performs and returns the first set of values from the lookup table. After this initial search, the app works exactly as expected. Is it possible to suppress this initial search (or have a default value) and perform the search ONLY when the submit button is pressed? I can't present reproducible code, but here is the structure of my input (server.R) and my user-interface (ui.R) code:
#server.R snippet
output$Word <- renderText({
predictWord <- input$gram
predict.function(predictWord) #User-defined function in global.r file
})
#ui.R snippet
tabPanel("Word Prediction",
sidebarPanel(
textInput("gram", "Enter up to three words"),
submitButton("Predict")),
mainPanel(
h4("Word Prediction"),
textOutput("predictWord")))
One way would be to substitute actionButton in place of submitButton and wrap whichever component in an if statement. Here is a simple example to display a number only slightly modified from the Shiny Widget Gallery.
require(shiny)
runApp(list(
ui = pageWithSidebar(
headerPanel("actionButton test"),
sidebarPanel(
numericInput("n", "N:", min = 0, max = 100, value = 50),
br(),
actionButton("goButton", "Go!"),
p("Click the button to update the value displayed in the main panel.")
),
mainPanel(
verbatimTextOutput("nText")
)
),
server = function(input, output){
output$nText <- renderText({
# Take a dependency on input$goButton
if(input$goButton >= 1){
# Use isolate() to avoid dependency on input$n
isolate(input$n)
}
})
}
)
)