├── README.md
├── webr-quarto-html-demo.html
├── webr-quarto-html-demo.qmd
├── webr-serviceworker.js
└── webr-worker.js
/README.md:
--------------------------------------------------------------------------------
1 | # webR-quarto-demos
2 |
3 | This repository houses experiments with generating a standalone [Quarto Document](https://quarto.org/) using [WebR](https://docs.r-wasm.org/webr/latest/).
4 |
5 | - [Proof of Concept: Quarto HTML Document with WebR](https://rd.thecoatlessprofessor.com/webR-quarto-demos/webr-quarto-html-demo.html) ([Source](webr-quarto-html-demo.qmd))
6 |
7 | You can create WebR-powered Quarto code cells using the [`quarto-webr`](https://github.com/coatless/quarto-webr) extension:
8 |
9 |
10 |
11 | ## Background
12 |
13 | [WebR v0.1.0](https://twitter.com/gwstagg/status/1633821049329537025) was launched on March 9th
14 | by George Stagg ([georgestagg](https://github.com/georgestagg)) and Lionel Henry ([lionel-](https://github.com/lionel-)). The goal of webR is to:
15 |
16 | > run R code in the browser without the need for an R server to execute the code
17 |
18 | This is an _amazing_ advancement of _R_ and has major implications with teaching R to the masses in an active learning context!
19 |
20 | ## Acknowledgements
21 |
22 | This repository leans _heavily_ on the webR developers public-facing examples:
23 |
24 | - [Source of Tidyverse Blog Post](https://github.com/tidyverse/tidyverse.org/pull/617/files) and [Minor fix](https://github.com/tidyverse/tidyverse.org/commit/72bb2dd7ca0b2f211498a891aa54f55ddcad5014)
25 | - [webR documentation landing page](https://github.com/r-wasm/webr/blob/53acd8861c44f1f167941d0a40f62b0cc23852da/src/docs/index.qmd#L23-L68) ([Live page](https://docs.r-wasm.org/webr/latest/))
26 |
--------------------------------------------------------------------------------
/webr-quarto-html-demo.qmd:
--------------------------------------------------------------------------------
1 | ---
2 | title: "webR with Quarto HTML Standalone Document Proof of Concept"
3 | subtitle: "Experiments with an Interactive Quarto Document using webR v0.1.0"
4 | author: "JJB leaning heavily on webR authors"
5 | engine: knitr
6 | execute:
7 | echo: true
8 | error: true
9 | embed-resources: true
10 | format:
11 | html:
12 | toc: true
13 | editor: source
14 | ---
15 |
16 | # Demo
17 |
18 | ## Background
19 |
20 | The purpose of this document is to explore how WebR can be embedded in a
21 | Quarto Document for the purposes of teaching _R_.
22 |
23 | - WebR Website:
24 | - WebR GitHub:
25 |
26 | ## Setup
27 |
28 | See the for source.
29 |
30 | ```{=html}
31 |
32 |
42 |
43 |
44 |
56 | ```
57 |
58 | ```{r}
59 | #| results: asis
60 | #| echo: false
61 | webr_counter = 0
62 |
63 | cat("importScripts('https://webr.r-wasm.org/v0.1.0/webr-worker.js');", file = "webr-worker.js")
64 | cat("importScripts('https://webr.r-wasm.org/v0.1.0/webr-serviceworker.js');", file = "webr-serviceworker.js")
65 |
66 | webr_editor = function(code = I(encodeString(code, quote = '`')), width, height) {
67 | webr_counter <<- webr_counter + 1
68 |
69 | output = glue::glue('
70 |
71 |
72 |
73 |
148 | ', .open = "{{", .close = "}}")
149 | }
150 | ```
151 |
152 | ```{r}
153 | #| echo: false
154 | knitr::knit_engines$set(webr = function(options) {
155 | code = paste(options$code, collapse = "\n")
156 | w = knitr::opts_current$get('fig.width') * 72
157 | h = knitr::opts_current$get('fig.height') * 72
158 | options$results = 'asis'
159 |
160 | form = webr_editor(code = I(encodeString(code, quote = '`')), width = w, height = h)
161 |
162 | form
163 | }
164 | )
165 | ```
166 |
167 | ## Exploration
168 |
169 | Next, let's look at a few features of the language
170 |
171 | ### Linear Regression
172 |
173 | We'll first start with the WebR team's demo example or the statistician way of
174 | saying, "Hello world!"... Aka linear regression:
175 |
176 | ```{webr}
177 | fit = lm(mpg ~ am, data=mtcars)
178 | summary(fit)
179 | ```
180 |
181 | ### Retrieving prior objects
182 |
183 | Each WebR cell appears to be connected to each other. Thus, we can access the
184 | `fit` outcome:
185 |
186 | ```{webr}
187 | coef(fit)
188 | ```
189 |
190 | ```{webr}
191 | anova(fit)
192 | ```
193 |
194 | ### Mixing active and non-active _R_ code
195 |
196 | For _if-else_ statements, we have:
197 |
198 | ```r
199 | if (...) {
200 | # Statements for TRUE
201 | } else {
202 | # Statements for FALSE
203 | }
204 | ```
205 |
206 | - `...` denotes a condition (either `TRUE` or `FALSE`)
207 | - If `TRUE`, then run the statements inside `{}`
208 | - Else, `FALSE`, carry on with your day.
209 |
210 | How could we modify `temperature` to have the `if` statement print `"Hot!"`?
211 |
212 | ```{webr}
213 | # Let's classify
214 | temperature = 60
215 |
216 | if (temperature > 76) {
217 | print("Hot!")
218 | } else {
219 | print("Cold!")
220 | }
221 | ```
222 |
223 |
224 | ### Summarize Data
225 |
226 | Glancing at data frames yields:
227 |
228 | ```{webr}
229 | summary(mtcars)
230 | ```
231 |
232 | ### Errors and Warnings
233 |
234 |
235 | ```{webr}
236 | stop("What happens if an error is present?")
237 | ```
238 |
239 | ```{webr}
240 | warning("You shouldn't be here...")
241 | ```
242 |
243 |
244 | ### Base graphics
245 |
246 | Graphing with base R
247 |
248 | ```{webr}
249 | plot(pressure)
250 | ```
251 |
252 | More advanced base R graphing...
253 |
254 | ```{webr}
255 | x1 = seq(0, 1, length = 20)
256 | y1 = rep(0, 20)
257 | x2 = rep(0, 20)
258 | y2 = seq(0.75, 0, length = 20)
259 |
260 | plot(0, type = "n",
261 | axes = FALSE, ylab = "", xlab = "",
262 | xlim = c(0, 1), ylim = c(0, 0.75), asp = 1,
263 | main = "Straight Lines as a Curve")
264 |
265 | segments(x1, y1, x2, y2)
266 | box(col = "grey")
267 | ```
268 |
269 | ### ggplot2 Graphics
270 |
271 | Next, we look at using `ggplot2` graphics. By default, the `ggplot2` package
272 | is not available as it is _dependency_ heavy.
273 |
274 | ```{=html}
275 |
276 |
277 | Package installation for `ggplot2` given by `webr::install("ggplot2")`
278 |
279 | Downloading webR package: cli
280 | Downloading webR package: glue
281 | Downloading webR package: gtable
282 | Downloading webR package: isoband
283 | Downloading webR package: rlang
284 | Downloading webR package: lifecycle
285 | Downloading webR package: MASS
286 | Downloading webR package: lattice
287 | Downloading webR package: nlme
288 | Downloading webR package: Matrix
289 | Downloading webR package: mgcv
290 | Downloading webR package: farver
291 | Downloading webR package: labeling
292 | Downloading webR package: colorspace
293 | Downloading webR package: munsell
294 | Downloading webR package: R6
295 | Downloading webR package: RColorBrewer
296 | Downloading webR package: viridisLite
297 | Downloading webR package: scales
298 | Downloading webR package: fansi
299 | Downloading webR package: magrittr
300 | Downloading webR package: utf8
301 | Downloading webR package: vctrs
302 | Downloading webR package: pillar
303 | Downloading webR package: pkgconfig
304 | Downloading webR package: tibble
305 | Downloading webR package: withr
306 | Downloading webR package: ggplot2
307 |
308 | ```
309 |
310 | ```{webr}
311 | # Install non-base R packages
312 | webr::install("ggplot2")
313 | # Load non-base packages like normal
314 | library("ggplot2")
315 | p = ggplot(mpg, aes(class, hwy))
316 | p + geom_boxplot()
317 | ```
318 |
319 |
320 |
321 |
--------------------------------------------------------------------------------
/webr-serviceworker.js:
--------------------------------------------------------------------------------
1 | importScripts('https://webr.r-wasm.org/v0.1.0/webr-serviceworker.js');
2 |
--------------------------------------------------------------------------------
/webr-worker.js:
--------------------------------------------------------------------------------
1 | importScripts('https://webr.r-wasm.org/v0.1.0/webr-worker.js');
2 |
--------------------------------------------------------------------------------