I would like to add hover tooltips to my input and output boxes on a shiny app that is deployed in shinyapps.io.
I found the RLumShiny package which can add tooltips and I have modified my app to accommodate this. The app works locally but when I try to deploy it to shinyapps.io I end up with the error seen below. There are no companion files to the app - just the ui.R and server.R files.
To deploy I run
library(rsconnect)
deployApp('~/sandbox/overdiag/', logLevel="verbose")
I get an error message
----- Deployment error -----
Error: C stack usage 7969336 is too close to the limit
(and a bunch of other information from the track). I've made a minimal example that produces the same error where the ui.R is
## ui.R ##
library("shiny")
library("RLumShiny") ## This package is problematic
library("shinydashboard")
library("shinyWidgets")
dashboardPage(
dashboardHeader(),
dashboardSidebar(),
dashboardBody()
)
and server.R
library("shiny")
library("RLumShiny") ## Again this package
library("shinydashboard")
function(input, output, session) {
}
Now if I remove the library("RLumShiny") line then everything works fine and I can deploy it right away. I don't get information that the package is not available but maybe there is something else wrong (I have a nagging feeling that the javascript in the package might do some things that the shinyapps.io service does not like).
Now: is there an alternative approach (ie., some other package) to get hover tooltips on the shinyapps.io or can I do something else to get RLumShiny to work?
In general in shiny you can get tooltips by using tags$div in your ui.r to wrap your controls / outputs and giving it a title. So for example you could do:
tags$div(title="My tooltip", plotOutput(outputId="MyPlot"))
and you will get a tool tip. The same pattern works for controls.
Related
I am trying to work through the R Studio Shiny tutorials. The second tutorial includes embedding an image into an app. It seems straight-forward and a similar question-and-answer here seems to use the same approach:
Embedding Image in Shiny App
However, I cannot get this approach to work. Here is a stripped-down version of R Studio's second tutorial code and a screenshot of the result I get. I have the png file in my working directory. Must the photo be placed somewhere else?
setwd('C:/Users/mark_/Documents/RShiny/')
library(shiny)
ui <- fluidPage(
titlePanel('Shiny App with Photo'),
sidebarLayout(
sidebarPanel(
h2("Installation"),
p("Shiny is on CRAN"),
br(),
img(src = "myScreenshot.png", height = 70, width = 200),
br()
),
mainPanel(
h1("Shiny"),
p("Shiny is a package from RStudio"),
br()
)
)
)
server <- function(input, output) {
}
shinyApp(ui = ui, server = server)
EDIT to Add Additional Steps Taken
When I originally posted my issue with R Shiny I was using the default R GUI. I have since switched to R Studio in case R Shiny works best that way. But this has not helped.
I have installed Rtools and added the following code to the very top of the above app.R file:
install.packages('zip')
install.packages('shinyjs')
install.packages('shinydashboard')
install.packages('shinyBS')
install.packages('shinyWidgets')
library(zip)
library(shinyjs)
library(shinydashboard)
library(shinyBS)
library(shinyWidgets)
install.packages('backports')
library(backports)
install.packages('devtools')
library(devtools)
rm(list=ls())
getwd()
setwd('C:/Users/mark_/Documents/RShiny/')
getwd()
library(shiny)
But this has not helped either.
As suggested by #MattB below I have created a subfolder named www inside the folder C:/Users/mark_/Documents/RShiny and place the file myScreenshot.png inside that www subfolder. However, this has not solved the problem. The image still does not appear.
I also tried placing the file myScreenshot.png inside that www subfolder of the RStudio folder under Program Files (C:\Program Files\RStudio\www) but this has not helped.
The image does not appear under the Open in Browser tab or under the http:// tab.
There are two options I have not yet tried. Perhaps I must change the name of the folder containing the app.R file (C:/Users/mark_/Documents/RShiny) to something other than RShiny. Perhaps that is confusing R Studio.
There is another issue that perhaps is preventing R Studio from locating the image file. When I install an R package I get the following message:
> install.packages('reshape2')
Installing package into ‘C:/Users/mark_/Documents/R/win-library/4.0’
(as ‘lib’ is unspecified)
also installing the dependency ‘plyr’
I end up with both:
C:\Program Files\R\R-4.0.0
C:\Users\mark_\Documents\R\win-library\4.0
I wonder whether that has anything to do with R Studio not being able to locate the image file.
For any files to be available to the app user, they need to be placed in the /www directory within your app folder. You don't need to change your code otherwise, as the user's browser will see this folder automatically.
I was able to get the R script to run in R Studio and display an image file by following suggestions by Dean Attali #DeanAttali at this website.
https://deanattali.com/blog/building-shiny-apps-tutorial/
I renamed the folder to Shineexample2 and placed that folder directly in the Documents folder. (C:\Users\mark_\Documents\Shineexample2) This was not one of Dean Attali's suggestions but the rest of the following was or was at least how I interpreted his suggestions.
This new folder Shineexample2 only contained the file app.R and the www subfolder containing the image file.
I opened the app.R file in R Studio, not the default R GUI, using File then Open File....
Then I clicked on Run App in the upper middle area of the R Studio GUI.
The file ran as expected.
The above process differed from my earlier attempts in several ways. Previously the app.R file was in a folder with a different name and containing many other files and subfolders. Usually I opened the file app.R in Notepad and copied and pasted its contents into R Studio. Then I selected all of the code and ran it using Code then Run Selected Line(s). I never noticed the Run App term at the top of the R Studio Gui before visiting Dean's website.
If I determine exactly which of these changes was most critical to successful execution of my code I may edit this answer in the future to provide that information.
Here are the complete contents of the app.R file that ran successfully.
#
# Stack_Overflow_Shiny_question_about_embedding_images_May22_2020.R
#
# install.packages('shiny')
# install.packages('zip')
# install.packages('shinyjs')
# install.packages('shinydashboard')
# install.packages('shinyBS')
# install.packages('shinyWidgets')
# install.packages('devtools')
#
library(shiny)
library(zip)
library(shinyjs)
library(shinydashboard)
library(shinyBS)
library(shinyWidgets)
install.packages('backports')
library(backports)
library(devtools)
rm(list=ls())
getwd()
setwd('C:/Users/mark_/Documents/Shineexample2/')
getwd()
library(shiny)
ui <- fluidPage(
titlePanel('Shiny App with Photo'),
sidebarLayout(
sidebarPanel(
h2("Installation"),
p("Shiny is on CRAN"),
br(),
img(src = "RStudio.png", height = 70, width = 200),
br()
),
mainPanel(
h1("Shiny"),
p("Shiny is a package from RStudio"),
br()
)
)
)
server <- function(input, output) {
}
shinyApp(ui = ui, server = server)
I have a app that works just fine without adding shinycssloaders package. But for some reason, after I added the package and added the lines (see below), it stopped working if I deploy it with shinyapps.io. The app runs fine locally, just wouldn't let me deploy it.
# load the library
library(shinycssloaders)
withSpinner(plotOutput("my_plot"))
# if you have `%>%` loaded, you can do plotOutput("my_plot") %>% withSpinner()
The error message I'm getting in the log is attached down below, but I have package shinycssloaders, and I've tried downloading it from CRAN and github, but neither works.
2019-05-13T16:41:39.317482+00:00 shinyapps[890504]: Using pandoc at /opt/connect/ext/pandoc2
2019-05-13T16:41:39.538904+00:00 shinyapps[890504]: Listening on http://127.0.0.1:46817
2019-05-13T16:41:43.893648+00:00 shinyapps[890504]: Warning: Error in withSpinner: could not find function "withSpinner"
2019-05-13T16:41:43.908035+00:00 shinyapps[890504]: 68: div
2019-05-13T16:41:43.908036+00:00 shinyapps[890504]: 67: mainPanel
2019-05-13T16:41:43.908034+00:00 shinyapps[890504]: 69: tags$div
2019-05-13T16:41:43.908032+00:00 shinyapps[890504]: 70: tag
I'm sure this work because it is on their github page, but I'm not sure what I did wrong. Worst case scenario, I'll just get rid of it so it's not a huge issue, but it'd be cool if I can use it. Any help is appreciated!
EDIT
So I attached a sample code, feel free try to deploy it, did't work for me. But works fine locally (since it's a sample app, the loading spinner is extremely quick, but you'd still be able to see it).
library(shiny)
library(shinycssloaders)
ui <- fluidPage(
actionButton("go", "Go"),
numericInput("n", "n", 50),
withSpinner(plotOutput("my_plot"))
)
server <- function(input, output) {
randomVals <- eventReactive(input$go, {
runif(input$n)
})
output$my_plot <- renderPlot({
hist(randomVals())
})
}
shinyApp(ui, server)
Since the log says Warning: Error in withSpinner: could not find function "withSpinner"
I went ahead added the package name in front of withSpinner function, so now in the UI function, it should be
shinycssloaders::withSpinner(plotOutput("my_plot", height = 600))
and it works perfect with deploy. Although it seems bizarre, because I indeed attached library(shinycssloaders). In my actual app, I attached it in server.R file, perhaps that's why.
I am trying to embed a tutorial Rmd from the learnr package into a full shiny app. However, learnr uses the shiny_prerendered runtime, I cannot call it within my app. How do I get an interactive tutorial to run within my shiny app?
I have have three files right now: ui.R, server.R, and tutorial.Rmd.
My tutorial looks like this (one ` removed for formatting)
---
title: "my tutorial"
tutorial:
id: "com.example.tutorials.a-tutorial"
version: 1.0
output: learnr::tutorial
runtime: shiny_prerendered
---
``{r setup, include=FALSE}
library(learnr)
knitr::opts_chunk$set(echo = FALSE)
``
### Exercise Example
An R code question
``{r add-function, exercise=TRUE, exercise.lines = 5}
add <- function() {
}
``
### Quiz
R Quiz Question
``{r quiz}
quiz(
question("Question 1",
answer("wrong"),
answer("also wrong"),
answer("right", correct = TRUE),
answer("wrong again")
)
)
``
When I try rendering the output of this file from ui.R like so:
ui <- tagList(
fluidPage(theme = shinytheme("cosmo")),
navbarPage(
"appTitle",
tabPanel("Embedding Tutorials?",
includeMarkdown("tutorial.Rmd")
),
)
)
It (properly, I believe) displays it as a regular old Rmd file, not an interactive tutorial.
I've also tried using rmarkdown::render("tutorial.Rmd") which just renders the filepath to the html file generated by the Rmd (/Users/me/app/tutorial.html).
When I try to render any tutorial using run_tutorial("hello", package="learnr"), it (again, rightfully) gives the error
ERROR: Can't callrunApp()from withinrunApp(). If your application code containsrunApp(), please remove it.
I've already discovered that I can create question chunks using the question() function in learnr using the following:
ui <- tagList(
fluidPage(theme = shinytheme("cosmo")),
navbarPage(
"appTitle",
tabPanel("Tutorial",
quiz(
question("Quiz question",
answer("1"),
answer("2"),
answer("3", correct = TRUE),
answer("4"),
allow_retry = TRUE
)
),
)
)
But this does not allow the functionality of creating R code chunks that can be run within the app.
What I want is a fully interactive learnr tutorial that can be rendered from within a ui.R file for a shiny app. Is this possible?
As well as my suggestion to incorporate your extra material into the learnr tutorial I also got <iframe> embedding to work. Create an app.R with the following contents:
#
# This is a Shiny web application. You can run the application by clicking
# the 'Run App' button above.
#
# Find out more about building applications with Shiny here:
#
# http://shiny.rstudio.com/
#
library(shiny)
# Define UI for application that draws a histogram
ui <- fluidPage(
# Application title
titlePanel("learnr tutorial"),
# Show a plot of the generated distribution
mainPanel(fluidRow(
htmlOutput("frame")
))
)
# Define server logic required to draw a histogram
server <- function(input, output) {
output$frame <- renderUI({
tags$iframe(
src="https://jjallaire.shinyapps.io/learnr-tutorial-03a-data-manip-filter/", width=1280, height=720
)
})
}
# Run the application
shinyApp(ui = ui, server = server)
Now when you Run App this should embed the example tutorial from https://rstudio.github.io/learnr/
It appears to be necessary for the tutorial to be rendered and published to shinyapps.io, etc.: I couldn't get it to work just from the rendered html file. So,
Create tutorial
Publish tutorial
Embed tutorial
seems to be the way forward.
Generally speaking, there are two ways to embed interactive RMarkdown documents in shiny applications.
(1) The usual way (as proposed by #Phil) is to have one R server running the embedded tutorial and another one running the application. This can be archived by deploying the tutorial via shinyapps.io or shiny-server first and then using an iframe. Alternatively, you could use callr::r_bg() to run the tutorial in a local background process. In any case, this will make it so the Rmd document can not interact with the shiny application. If this is feasable for your usecase, I would suggest this option.
(2) A more convoluted way is outlined here by the maintainer of the shinyAce package. It uses the same R server for the main application and the embedded Rmd document. See also this SO question. AFAIK, this only works with knitr::knit2html which relies on an outdated version of RMarkdown. Also, the amount of render* and output* functions available in this manner is limited unless you make sure certain JavaScript and CSS resources are properly included in your ui definition.
Quite some time has passed since I wrapped my head around this topic but my impression at the time was, that (2) takes quite a lot of work and really limits your options.
I am rather new in shiny, so I was running through some tutorials. However, I have a problem loading images from a file inside the "www" folder of the shiny app.
For example, when I run the code below, I get a missing image. However, if I refer to an image online, e.g., if I substitute "bigorb.png" by "http://shiny.rstudio.com/tutorial/lesson2/www/bigorb.png", I get the desired image without problems. I am using R version 3.3.1 on Windows 10. Can anyone help me?
ui <- shinyUI(fluidPage(
titlePanel("My Shiny App"),
sidebarLayout(
sidebarPanel(),
mainPanel(
img(src="bigorb.png", height = 400, width = 400)
)
)
))
server <- shinyServer(function(input, output) {
})
shinyApp(ui = ui, server = server)
This works for me:
Create folder /myApp
Inside /myApp: create a file starter.R with the following code, and make sure to set the working directory correctly:
library(shiny)
setwd("PATH_TO_myApp")
shiny::runApp("app")
In the folder /myApp, create a subfolder /app.
In /myApp/app/: create file "app.R" with your code from above.
Create another sub-subfolder /myApp/app/www/ . Include your image file.
Execute starter.R.
So your file list is:
/myApp/starter.R
/myApp/app/app.R
/myApp/app/www/bigorb.png
Is it possible to write R Code within the shiny app while it's running? I've built a shiny app, but would like to give users the option to write their own R code in the shiny app. I want to put the console in shiny along with the viewer and a simplified environment pane. I've never seen anything like this, so before I spend a lot of time doing this I'm wondering if it's even possible. Has anyone seen something like this?
Thanks to Cory I found rfiddle, which is exactly what I'm looking for. However I can't seem to get it to work. I used the iframe that r-fiddles website says to use to embed rfiddle, but I keep getting this error message:
Error in withReactiveDomain(shinysession, { :
No handler registered for for type .clientdata_output_<iframe width="300" height="600" src="http://r-fiddle.org/#/embed/eYsWfghB/1" allowfullscreen="allowfullscreen" frameborder="0"></iframe>_hidden
Code:
library(shiny)
ui = shinyUI(
fluidPage(
htmlOutput(tags$iframe(width=300, height=600,
src='http://r-fiddle.org/#/embed/eYsWfghB/1',
allowfullscreen='allowfullscreen', frameborder='0'))
)
)
server = shinyServer(function(input, output, session) {
})
shiny::shinyApp(ui,server)