I am using DT::datatable() to visualize tables in a R markdown file.
# R markdown file
library(DT)
```{r viewdata}
# this is an example but my actual dataset has 10000 rows and 100 columns
var.df <- data.frame(x = rnorm(1:10000), y = rnorm(1:10000),...)
DT::datatable(data = var.df)
```
When I run this code, I get a warning and the resulting HTML is very slow to load:
DT::datatable(var.df)
Warning message:
In instance$preRenderHook(instance) :
It seems your data is too big for client-side DataTables. You may consider server-side processing: http://rstudio.github.io/DT/server.html
I know that there is a server = TRUE/FALSE option in DT::renderDataTable(), but I don't see any server option in DT::datatable.
How do I use serverside processing using DT::datatable()?
The warning message says:
It seems your data is too big for client-side DataTables. You may consider server-side processing: http://rstudio.github.io/DT/server.html
On the documentation website, it shows a Shiny example, which uses DT::renderDataTable(). To use the server-side processing mode, you must have a "server" in the first place. DT::datatable() only produces a static HTML widget, and there is no server behind it. All data live in and is processed by your web browser.
Shiny is not the only possible server for DT, but probably the most convenient one (unless you really understand the technical details behind server-side processing). To use Shiny with R Markdown, see Chapter 19 of the R Markdown book. Here is an example:
---
title: "The server-side processing mode for DT in R Markdown"
runtime: shiny
output: html_document
---
```{r}
DT::renderDT(ggplot2::diamonds)
```
Related
Motivation: I want to write an interface that uses questions from the R package exams in learnr questions/quizzes. In R/exams each question is either an R/Markdown (Rmd) or R/LaTeX (Rnw) file with a certain structure specifying question, solution, and further meta-information. The questions can contain R code to make them dynamic, e.g., sampling numbers or certain text building blocks etc. Hence, the workflow is that first the questions are run through knitr::knit or utils::Sweave and then embedded in a suitable output format.
Problem: When I rmarkdown::run("learnr+rexams.Rmd") a learnr tutorial that dynamically produces a question or quiz from an Rmd exercise I get the error:
Error in if (grepl(not_valid_char_regex, label)) { :
argument is of length zero
The code for a simple reproducible example learnr+rexams.Rmd is included below.
The reason for the error appears to be that learnr runs a function verify_tutorial_chunk_label() that tries to assure the the learnr R chunk labels are well formatted. However, confusion is caused by the chunks that are run by the R/exams package, unnecessarily leading to the error above.
Workarounds: I can disable the verify_tutorial_chunk_label() in the learnr namespace and then everything works well. Or I can use Rnw instead of Rmd exercises and then learnr does not conflict with Sweave(). Also, when I run my code outside of a learnr tutorial it works fine.
Question: Can I do anything less invasive to make exams cooperate with learnr? For example, setting some appropriate knitr options or something like that?
Example: This is the source for the minimal learnr tutorial learnr+rexams.Rmd that replicates the problem. Note that everything is very much simplified and only works for certain R/exams exercises, here using the function exercise template that ships with R/exams.
---
title: "learnr & R/exams"
output: learnr::tutorial
runtime: shiny_prerendered
---
```{r exams2learnr, include = FALSE}
exams2learnr <- function(file) {
x <- exams::xexams(file)[[1]][[1]]
x <- list(text = x$question, type = "learnr_text",
learnr::answer(x$metainfo$solution, correct = TRUE))
do.call(learnr::question, x)
}
## assignInNamespace("verify_tutorial_chunk_label", function() return(), ns = "learnr")
```
```{r rfunctions, echo = FALSE, message = FALSE}
exams2learnr("function.Rmd")
```
Running this tutorial (as noted above) replicates the error. To avoid it I can either uncomment the assignInNamespace() call or alternatively replace "function.Rmd" by "function.Rnw".
The problem is that by the time learnr::question() is called, knitr is no longer able to find the chunk label for the chunk where exams2learnr() was called. You can get around this by setting the current chunk label before calling do.call(learnr_question, x):
exams2learnr <- function(file, label = knitr::opts_current$get("label")) {
force(label)
x <- exams::xexams(file)[[1]][[1]]
x <- list(
text = x$question,
type = "learnr_text",
learnr::answer(x$metainfo$solution, correct = TRUE)
)
knitr::opts_current$set(label = label)
do.call(learnr::question, x)
}
This also lets you set the label dynamically if you want, which becomes the ID of the question in learnr.
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 have a strange error in a shiny app I built with the library learnr. An error "Object not found" about an object I just loaded and just visualized (meaning the object exists no ?)
Although I don't have a reproducible example, some of you will maybe understand what is creating the error :
I have a first chunk {r load} that loads a dataset. There is no error here, I can even visualize the dataset (screenshot below)
Then I have a second chunk, where I would like to manipulate the dataset. But it tells me dataset doesn't exist ! How it could be possible, I just visualized it one chunk before ?! ...
I don't understand how a dataset could be exists in a chunk, and not in another. Does it mean the dataset isn't loaded in the global environment ? Is it a problem with the learnr library ?
Maybe someone will have an idea, or something I could test. Thank you in advance.
EDIT:
The problem is about the environment/workspace. In the first chunk, even if I load the dataset, it is not store in the environment. I tested the function ls() in a second chunk, and it tells me there is no object in the workspace. The loaded dataset is not here, I don't know why ...
In my opinion, shiny doesn't store any data. You have to pass it manually from one chunk to other as follow (only adding the code snippet from server):
server <- function(input, output, session) {
output$heat <- renderPlotly({
Name<-c("John","Bob","Jack")
Number<-c(3,3,5)
Count<-c(2,2,1)
NN<-data.frame(Name,Number,Count)
render_value(NN) # You need function otherwise data.frame NN is not visible
# You can consider this as chunk 1
})
render_value=function(NN){
# Here your loaded data is available
head(NN)
# You can consider this as chunk 2
})
}
}
shinyApp(ui, server)
You can find full code here: Subset a dataframe based on plotly click event
OR
Create global.R file as suggested here and follow this URL: R Shiny - create global data frame at start of app
I work with R in a linux server and would like to have a functionality similar to View() in RStudio where you can look at your dataset in a tabular format.
The problem is I will not have x11 enabled, this is not an option.
Is there any good alternative way?
You can use the package tableHTML which produces an HTML table that can be seen in the viewer and/or browser.
It is fairly easy to use, all you need to to is:
library(tableHTML)
tableHTML(mtcars, rownames = FALSE, theme = 'scientific')
This returns:
This is similar to clemens' answer but produces searchable and sortable output:
Use a parameterized report and knit it to HTML using rmarkdown::render. The resulting HTML file is opened in the default browser.
Create view_template.Rmd in your working directory with the following contents:
---
params:
myinput: ""
---
```{r, echo = FALSE}
DT::datatable(params$myinput, options = list(pageLength = 20))
```
To view a data set, run browseURL(rmarkdown::render(input = "view_template.Rmd", params = list(myinput = iris))), replacing iris by whichever data set is to be shown.
Of course, this could be wrapped in a nice helper function to get code that is better readable and easier to (re-) use. You need to install the packages DT and rmarkdown before running the code.
Tested on Windows 10; hopefully passing a file path to browseURL works on Linux as well.
Output:
I would like to send to someone else a presentation that I have created using R and slidfy, but it contains sensitive information, so putting it up onto github pages using the gh-pages branch and then sending the URL isn't really an option, since all github pages are public, as suggested here.
Pushing it up to the glimmer shiny server as well seems a bit unsecure too...(I would ideally like to do this for free so setting up a server to host the one presentation seems a bit cumbersome and overkill for my purposes)
I don't think dropbox would work either since any URL link that is produced if someone else types it into an address bar, would probably be able to download it and view the sensitive information...
Is there a way of sending the presentation (by email or other methods) that contains all the necessary files for it to work, so that a person who doesn't use R can open it and view it easily. (i.e. without having to send them a zip file of all the files (i.e. the assets and libraries and figure folders etc), asking them to unzip it and then opening the index.html file)?
Edit
I forgot to mention that the presentations include nvd3 and morrisjs graphs too, making it difficult to bring over all the files in one go...
Edit2
Given all the libraries used are public libraries, is there a way for it to reference a URL instead of a local drive?
Here is how you would do it with Slidify. There are two tricks to use.
Specify mode: standalone in your YAML front matter. This makes sure that all slide related JS and CSS assets are served from an online CDN, and also that all static images are converted into data URLs.
Use n1$print('mychart', include_assets = TRUE, cdn = TRUE) when you print the chart in your knitr code chunk. This makes sure that all chart relate assets are included and served from an online CDN. Note that for each library, you should use include_assets only once, so that you don't duplicate.
This approach is not very robust since you are linking to multiple JS libraries in a single file, and as a result there could be conflicts. Case in point, MorrisJS does not play well with Google IO2012, since Google IO2012 uses requireJS and for some reason raises conflicts.
You can also use the same code chunks in RStudio Presentations and save them as standalone HTML. Here is the same presentation in RPres format.
---
title : Standalone Presentation with Slidify
author : Ramnath Vaidyanathan
mode : standalone
---
## Plain Text
This is a slide with plain text
> 1. Point 1
> 2. Point 2
> 3. Point 3
---
## R Plot
```{r message = F}
require(ggplot2)
qplot(wt, mpg, data = mtcars)
```
---
## NVD3 Plot
```{r results = 'asis', comment = NA, message = F, echo = F}
require(rCharts)
n1 <- nPlot(mpg ~ wt, data = mtcars, type = 'scatterChart', group = 'gear')
n1$print('chart2', include_assets = TRUE, cdn = TRUE)
```
<style>
.rChart {
height: 500px;
}
</style>
---
## Another NVD3 Plot
```{r results = 'asis', comment = NA, message = F, echo = F}
require(rCharts)
n2 <- nPlot(mpg ~ cyl, data = mtcars, type = 'scatterChart')
n2$print('chart3')
```
Another option is to
1) Open the HTML file in Chrome,
2) Choose the option to print
3) Save it as .pdf.
It's not perfect for all cases but definately a decent option to consider.
I think your last method is the safest.
Do you really want to use slidify? With the latest (preview) version of Rstudio you can create HTML5 presentations on the fly. And it is much easier than slidify. To distribute the slideshow you just have to mail the standalone output html file (if you aren't using fancy things like nvd3 or latex).
Here is some more information.
link1
link2
link3