├── webr-worker.js ├── webr-serviceworker.js ├── .gitignore ├── webr-setup.html ├── README.md ├── webr-quarto.qmd ├── _webr-setup.qmd └── webr-quarto-html-demo.qmd /webr-worker.js: -------------------------------------------------------------------------------- 1 | importScripts('https://webr.r-wasm.org/v0.1.0/webr-worker.js'); -------------------------------------------------------------------------------- /webr-serviceworker.js: -------------------------------------------------------------------------------- 1 | importScripts('https://webr.r-wasm.org/v0.1.0/webr-serviceworker.js'); -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .Rproj.user 2 | .Rhistory 3 | .RData 4 | .Ruserdata 5 | webR-quarto-demos.Rproj 6 | -------------------------------------------------------------------------------- /webr-setup.html: -------------------------------------------------------------------------------- 1 | 2 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # webR-quarto-demos 2 | 3 | This is a fork of https://github.com/coatless-r-n-d/webR-quarto-demos. I moved the setup code into separate html and qmd files and then use includes in the qmd. 4 | 5 | To make your own version: 6 | 7 | * Fork 8 | * Turn on GitHub Pages at main branch. 9 | * Go to your .github.io repo. Copy the files `webr-serviceworker.js` and `webr-worker.js` into them. I don't know why. But somehow the html can't find them otherwise. I am assuming you have GitHub Pages on for that repo so `.github.io` exists. 10 | * Your demo will now be visible at `.github.io/webR-quarto-demos/webr-quarto.html` 11 | 12 | I tried a few ways to get the html page to find the `webr-serviceworker.js` and `webr-worker.js` files in this demo repo, but no luck. I don't know html well enough. 13 | 14 | Example: 15 | 16 | * [rverse-tutorials.github.io/webR-quarto-demos/webr-quarto.html](rverse-tutorials.github.io/webR-quarto-demos/webr-quarto.html) 17 | * [rverse-tutorials.github.io/webR-quarto-demos/webr-quarto-html-demo.html](rverse-tutorials.github.io/webR-quarto-demos/webr-quarto-html-demo.html) 18 | 19 | ## Acknowledgements 20 | 21 | This is a fork of work by James J Balamuta: 22 | - [Quarto HTML Document with WebR](https://github.com/coatless-r-n-d/webR-quarto-demos) 23 | ] 24 | To explore use of WebR in Quarto. [WebR v0.1.0](https://twitter.com/gwstagg/status/1633821049329537025) was launched on March 9th 25 | by George Stagg ([georgestagg](https://github.com/georgestagg)) and Lionel Henry ([lionel-](https://github.com/lionel-)). 26 | 27 | The `_webr-setup.qmd` and `webr-setup.html` files are the key setup files and are all the work of James J Balamuta in this [file](https://github.com/coatless-r-n-d/webR-quarto-demos/blob/main/webr-quarto-html-demo.qmd). 28 | -------------------------------------------------------------------------------- /webr-quarto.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: "James J Balamuta; modified by EEH" 5 | repo: https://github.com/RVerse-Tutorials/webR-quarto-demos 6 | engine: knitr 7 | execute: 8 | echo: true 9 | error: true 10 | embed-resources: true 11 | format: 12 | html: 13 | toc: true 14 | code-tools: 15 | source: https://github.com/RVerse-Tutorials/webR-quarto-demos/blob/main/webr-quarto.qmd 16 | include-in-header: webr-setup.html 17 | repo-url: https://github.com/RVerse-Tutorials/webR-quarto-demos 18 | repo-actions: [edit, source] 19 | editor: source 20 | --- 21 | 22 | {{< include _webr-setup.qmd >}} 23 | 24 | # Background 25 | 26 | This is not my work. Forked from and go there to see how this works 27 | James J Balamuta: 28 | 29 | This was created by JJB to explore how [WebR](https://docs.r-wasm.org/webr/latest/) can be embedded in a Quarto Document for the purposes of teaching _R_. 30 | 31 | 32 | ## Setup 33 | 34 | The yaml includes this. Note the `webr-setup.html` and _webr-setup.qmd` files. 35 | ``` 36 | --- 37 | title: "the title" 38 | engine: knitr 39 | execute: 40 | echo: true 41 | error: true 42 | embed-resources: true 43 | format: 44 | html: 45 | toc: true 46 | include-in-header: webr-setup.html 47 | editor: source 48 | --- 49 | 50 | {{< include _webr-setup.qmd >}} 51 | ``` 52 | 53 | ## Calling WebR 54 | 55 | Use `{webr}` rather than `{r}` for your code. 56 | 57 | ### Linear Regression 58 | 59 | We'll first start with the WebR team's demo example or the statistician way of 60 | saying, "Hello world!"... Aka linear regression: 61 | 62 | ```{webr} 63 | fit = lm(mpg ~ am, data=mtcars) 64 | summary(fit) 65 | ``` 66 | 67 | ### Retrieving prior objects 68 | 69 | Each WebR cell appears to be connected to each other. Thus, we can access the 70 | `fit` outcome: 71 | 72 | ```{webr} 73 | coef(fit) 74 | ``` 75 | 76 | ```{webr} 77 | anova(fit) 78 | ``` 79 | 80 | ### Mixing active and non-active _R_ code 81 | 82 | ```{webr} 83 | # Let's classify 84 | temperature = 60 85 | ``` 86 | 87 | 88 | ```{webr} 89 | if (temperature > 76) { 90 | print("Hot!") 91 | } else { 92 | print("Cold!") 93 | } 94 | ``` 95 | 96 | 97 | ### Summarize Data 98 | 99 | Glancing at data frames yields: 100 | 101 | ```{webr} 102 | summary(mtcars) 103 | ``` 104 | 105 | ### Errors and Warnings 106 | 107 | 108 | ```{webr} 109 | stop("What happens if an error is present?") 110 | ``` 111 | 112 | ```{webr} 113 | warning("You shouldn't be here...") 114 | ``` 115 | 116 | 117 | ### Base graphics 118 | 119 | Graphing with base R 120 | 121 | ```{webr} 122 | plot(pressure) 123 | ``` 124 | 125 | More advanced base R graphing... 126 | 127 | ```{webr} 128 | x1 = seq(0, 1, length = 20) 129 | y1 = rep(0, 20) 130 | x2 = rep(0, 20) 131 | y2 = seq(0.75, 0, length = 20) 132 | 133 | plot(0, type = "n", 134 | axes = FALSE, ylab = "", xlab = "", 135 | xlim = c(0, 1), ylim = c(0, 0.75), asp = 1, 136 | main = "Straight Lines as a Curve") 137 | 138 | segments(x1, y1, x2, y2) 139 | box(col = "grey") 140 | ``` 141 | 142 | ### ggplot2 Graphics 143 | 144 | There is an extra step of installing packages that are not part of the base. 145 | 146 | CLICK RUN AND WAIT LIKE 1 MINUTE. When you see output, it means it is loaded. Be patient. 147 | 148 | ```{webr} 149 | # Install non-base R packages 150 | webr::install("ggplot2") 151 | ``` 152 | 153 | Now we can use ggplot2 in the qmd. 154 | ```{webr} 155 | library("ggplot2") 156 | p = ggplot(mpg, aes(class, hwy)) 157 | p + geom_boxplot() 158 | ``` 159 | 160 | 161 | 162 | -------------------------------------------------------------------------------- /_webr-setup.qmd: -------------------------------------------------------------------------------- 1 | ```{r} 2 | #| results: asis 3 | #| echo: false 4 | webr_counter = 0 5 | 6 | cat("importScripts('https://webr.r-wasm.org/v0.1.0/webr-worker.js');", file = "webr-worker.js") 7 | cat("importScripts('https://webr.r-wasm.org/v0.1.0/webr-serviceworker.js');", file = "webr-serviceworker.js") 8 | 9 | webr_editor = function(code = I(encodeString(code, quote = '`')), width, height) { 10 | webr_counter <<- webr_counter + 1 11 | 12 | output = glue::glue(' 13 | 14 |
15 |
16 | 91 | ', .open = "{{", .close = "}}") 92 | } 93 | ``` 94 | 95 | ```{r} 96 | #| echo: false 97 | knitr::knit_engines$set(webr = function(options) { 98 | code = paste(options$code, collapse = "\n") 99 | w = knitr::opts_current$get('fig.width') * 72 100 | h = knitr::opts_current$get('fig.height') * 72 101 | options$results = 'asis' 102 | 103 | form = webr_editor(code = I(encodeString(code, quote = '`')), width = w, height = h) 104 | 105 | form 106 | } 107 | ) 108 | ``` 109 | -------------------------------------------------------------------------------- /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: "James J Balamuta; modified by EEH" 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 | --------------------------------------------------------------------------------