From 9f132c3b4ce2a9f515a2f6759dcecb16a453f8e3 Mon Sep 17 00:00:00 2001 From: Salim B Date: Wed, 29 Jul 2020 23:58:00 +0200 Subject: [PATCH 1/3] Fix typo and case --- Perf-improve.Rmd | 2 +- Quotation.Rmd | 2 +- README.md | 2 +- Rcpp.Rmd | 2 +- S4.Rmd | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Perf-improve.Rmd b/Perf-improve.Rmd index c94f3c097..dc1faa334 100644 --- a/Perf-improve.Rmd +++ b/Perf-improve.Rmd @@ -199,7 +199,7 @@ bench::mark( )[c("expression", "min", "median", "itr/sec", "n_gc")] ``` -NB: most of these differences arise because `x` is small. If you increase the size the differences basically disappear, because most of the time is now spent computing the mean, not finding the underlying implementation. This is a good reminder that the size of the input matters, and you should motivate your optimisations based on realistic data. +NB: Most of these differences arise because `x` is small. If you increase the size the differences basically disappear, because most of the time is now spent computing the mean, not finding the underlying implementation. This is a good reminder that the size of the input matters, and you should motivate your optimisations based on realistic data. ```{r} x <- runif(1e4) diff --git a/Quotation.Rmd b/Quotation.Rmd index 0d93447b4..31675f164 100644 --- a/Quotation.Rmd +++ b/Quotation.Rmd @@ -1136,7 +1136,7 @@ new_function( ) ``` -NB: the empty arguments in `exprs()` generates arguments with no defaults. +NB: The empty arguments in `exprs()` generates arguments with no defaults. One use of `new_function()` is as an alternative to function factories with scalar or symbol arguments. For example, we could write a function that generates functions that raise a function to the power of a number. diff --git a/README.md b/README.md index 8f16f76d3..eea4b5afa 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ Book: * Inconsolata scaled (by fontspec) to match main font is 9.42pt. -* Preview at 100% matches physical size of book. Maxiumum diagram width is 11cm. +* Preview at 100% matches physical size of book. Maximum diagram width is 11cm. RMarkdown diff --git a/Rcpp.Rmd b/Rcpp.Rmd index 3d5374260..8d7372074 100644 --- a/Rcpp.Rmd +++ b/Rcpp.Rmd @@ -342,7 +342,7 @@ bench::mark( */ ``` -NB: if you run this code, you'll notice that `meanC()` is much faster than the built-in `mean()`. This is because it trades numerical accuracy for speed. +NB: If you run this code, you'll notice that `meanC()` is much faster than the built-in `mean()`. This is because it trades numerical accuracy for speed. For the remainder of this chapter C++ code will be presented stand-alone rather than wrapped in a call to `cppFunction`. If you want to try compiling and/or modifying the examples you should paste them into a C++ source file that includes the elements described above. This is easy to do in RMarkdown: all you need to do is specify `engine = "Rcpp"`. diff --git a/S4.Rmd b/S4.Rmd index 41f410adf..916aeba4e 100644 --- a/S4.Rmd +++ b/S4.Rmd @@ -517,7 +517,7 @@ knitr::include_graphics("diagrams/s4/multiple.png") The basic process remains the same: you start from the actual class supplied to the generic, then follow the arrows until you find a defined method. The wrinkle is that now there are multiple arrows to follow, so you might find multiple methods. If that happens, you pick the method that is closest, i.e. requires travelling the fewest arrows. -NB: while the method graph is a powerful metaphor for understanding method dispatch, implementing it in this way would be rather inefficient, so the actual approach that S4 uses is somewhat different. You can read the details in `?Methods_Details`. +NB: While the method graph is a powerful metaphor for understanding method dispatch, implementing it in this way would be rather inefficient, so the actual approach that S4 uses is somewhat different. You can read the details in `?Methods_Details`. What happens if methods are the same distance? For example, imagine we've defined methods for `r emoji("dark_sunglasses")` and `r emoji("slightly_smiling_face")`, and we call the generic with `r emoji("sunglasses")`. Note that no method can be found for the `r emoji("no_mouth")` class, which I'll highlight with a red double outline. From b9b34592a66b15e98d591df32dd011d7f4888eca Mon Sep 17 00:00:00 2001 From: Salim B Date: Thu, 30 Jul 2020 00:20:15 +0200 Subject: [PATCH 2/3] improve knitr `engine` doc and spell "R Markdown" with a space instead of "RMarkdown"; the former is the official way, cf. https://rmarkdown.rstudio.com/ --- Debugging.Rmd | 10 +++++----- Introduction.Rmd | 2 +- Names-values.Rmd | 2 +- Perf-improve.Rmd | 2 +- README.md | 2 +- Rcpp.Rmd | 14 +++++++++++++- 6 files changed, 22 insertions(+), 10 deletions(-) diff --git a/Debugging.Rmd b/Debugging.Rmd index 18868c227..bcc27c0bf 100644 --- a/Debugging.Rmd +++ b/Debugging.Rmd @@ -392,14 +392,14 @@ f(10) Print debugging is particularly useful for compiled code because it's not uncommon for the compiler to modify your code to such an extent you can't figure out the root problem even when inside an interactive debugger. -### RMarkdown -\index{debugging!RMarkdown} +### R Markdown +\index{debugging!R Markdown} -Debugging code inside RMarkdown files requires some special tools. First, if you're knitting the file using RStudio, switch to calling `rmarkdown::render("path/to/file.Rmd")` instead. This runs the code in the current session, which makes it easier to debug. If doing this makes the problem go away, you'll need to figure out what makes the environments different. +Debugging code inside R Markdown files requires some special tools. First, if you're knitting the file using RStudio, switch to calling `rmarkdown::render("path/to/file.Rmd")` instead. This runs the code in the current session, which makes it easier to debug. If doing this makes the problem go away, you'll need to figure out what makes the environments different. -If the problem persists, you'll need to use your interactive debugging skills. Whatever method you use, you'll need an extra step: in the error handler, you'll need to call `sink()`. This removes the default sink that knitr uses to capture all output, and ensures that you can see the results in the console. For example, to use `recover()` with RMarkdown, you'd put the following code in your setup block: +If the problem persists, you'll need to use your interactive debugging skills. Whatever method you use, you'll need an extra step: in the error handler, you'll need to call `sink()`. This removes the default sink that knitr uses to capture all output, and ensures that you can see the results in the console. For example, to use `recover()` with R Markdown, you'd put the following code in your setup block: ```{r, eval = FALSE} options(error = function() { @@ -410,7 +410,7 @@ options(error = function() { This will generate a "no sink to remove" warning when knitr completes; you can safely ignore this warning. -If you simply want a traceback, the easiest option is to use `rlang::trace_back()`, taking advantage of the `rlang_trace_top_env` option. This ensures that you only see the traceback from your code, instead of all the functions called by RMarkdown and knitr. +If you simply want a traceback, the easiest option is to use `rlang::trace_back()`, taking advantage of the `rlang_trace_top_env` option. This ensures that you only see the traceback from your code, instead of all the functions called by R Markdown and knitr. ```{r, eval = FALSE} options(rlang_trace_top_env = rlang::current_env()) diff --git a/Introduction.Rmd b/Introduction.Rmd index 5c0ee2ab0..7eb9bda10 100644 --- a/Introduction.Rmd +++ b/Introduction.Rmd @@ -28,7 +28,7 @@ If you are new to R, you might wonder what makes learning such a quirky language graphic you're trying to do, chances are that someone has already tried to do it and you can learn from their efforts. -* Powerful tools for communicating your results. [RMarkdown][rmarkdown] makes +* Powerful tools for communicating your results. [R Markdown][rmarkdown] makes it easy to turn your results into HTML files, PDFs, Word documents, PowerPoint presentations, dashboards and more. [Shiny][shiny] allows you to make beautiful interactive apps without any knowledge of HTML or javascript. diff --git a/Names-values.Rmd b/Names-values.Rmd index 1950a5ec1..56dd08770 100644 --- a/Names-values.Rmd +++ b/Names-values.Rmd @@ -222,7 +222,7 @@ knitr::include_graphics("diagrams/name-value/binding-3.png") This behaviour is called __copy-on-modify__. Understanding it will radically improve your intuition about the performance of R code. A related way to describe this behaviour is to say that R objects are unchangeable, or __immutable__. However, I'll generally avoid that term because there are a couple of important exceptions to copy-on-modify that you'll learn about in Section \@ref(modify-in-place). -When exploring copy-on-modify behaviour interactively, be aware that you'll get different results inside of RStudio. That's because the environment pane must make a reference to each object in order to display information about it. This distorts your interactive exploration but doesn't affect code inside of functions, and so doesn't affect performance during data analysis. For experimentation, I recommend either running R directly from the terminal, or using RMarkdown (like this book). +When exploring copy-on-modify behaviour interactively, be aware that you'll get different results inside of RStudio. That's because the environment pane must make a reference to each object in order to display information about it. This distorts your interactive exploration but doesn't affect code inside of functions, and so doesn't affect performance during data analysis. For experimentation, I recommend either running R directly from the terminal, or using R Markdown (like this book). ### `tracemem()` \indexc{tracemem()} diff --git a/Perf-improve.Rmd b/Perf-improve.Rmd index dc1faa334..42773275e 100644 --- a/Perf-improve.Rmd +++ b/Perf-improve.Rmd @@ -70,7 +70,7 @@ mean1 <- function(x) mean(x) mean2 <- function(x) sum(x) / length(x) ``` -I recommend that you keep a record of everything you try, even the failures. If a similar problem occurs in the future, it'll be useful to see everything you've tried. To do this I recommend RMarkdown, which makes it easy to intermingle code with detailed comments and notes. +I recommend that you keep a record of everything you try, even the failures. If a similar problem occurs in the future, it'll be useful to see everything you've tried. To do this I recommend [R Markdown](https://rmarkdown.rstudio.com/), which makes it easy to intermingle code with detailed comments and notes. Next, generate a representative test case. The case should be big enough to capture the essence of your problem but small enough that it only takes a few seconds at most. You don't want it to take too long because you'll need to run the test case many times to compare approaches. On the other hand, you don't want the case to be too small because then results might not scale up to the real problem. Here I'm going to use 100,000 numbers: diff --git a/README.md b/README.md index eea4b5afa..f39bfcb11 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ Book: * Preview at 100% matches physical size of book. Maximum diagram width is 11cm. -RMarkdown +R Markdown * Remove dpi specification from `include_graphics()`, instead relying on `common.R`. Chunk should have `output.width = NULL`. diff --git a/Rcpp.Rmd b/Rcpp.Rmd index 8d7372074..b56c68062 100644 --- a/Rcpp.Rmd +++ b/Rcpp.Rmd @@ -344,7 +344,19 @@ bench::mark( NB: If you run this code, you'll notice that `meanC()` is much faster than the built-in `mean()`. This is because it trades numerical accuracy for speed. -For the remainder of this chapter C++ code will be presented stand-alone rather than wrapped in a call to `cppFunction`. If you want to try compiling and/or modifying the examples you should paste them into a C++ source file that includes the elements described above. This is easy to do in RMarkdown: all you need to do is specify `engine = "Rcpp"`. +For the remainder of this chapter, C++ code will be presented stand-alone rather than wrapped in a call to `cppFunction`. If you want to try compiling and/or modifying the examples, you should paste them into a C++ source file that includes the elements described above. This is easy to do in R Markdown: all you need to do is specifying the right [knitr language engine chunk option](https://yihui.org/knitr/options/#language-engines): + +````rmd +```{engine = "Rcpp"} +``` +```` + +or [just](https://bookdown.org/yihui/rmarkdown/language-engines.html) + +````rmd +```{Rcpp} +``` +```` ### Exercises {#exercise-started} From 08f2141ed5ca43037afa6eb726ac7c9e945cd225 Mon Sep 17 00:00:00 2001 From: Salim B Date: Thu, 30 Jul 2020 00:30:37 +0200 Subject: [PATCH 3/3] Revert changes from separate PR #1625 --- Perf-improve.Rmd | 2 +- Quotation.Rmd | 2 +- README.md | 2 +- Rcpp.Rmd | 2 +- S4.Rmd | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Perf-improve.Rmd b/Perf-improve.Rmd index 42773275e..335b84cc6 100644 --- a/Perf-improve.Rmd +++ b/Perf-improve.Rmd @@ -199,7 +199,7 @@ bench::mark( )[c("expression", "min", "median", "itr/sec", "n_gc")] ``` -NB: Most of these differences arise because `x` is small. If you increase the size the differences basically disappear, because most of the time is now spent computing the mean, not finding the underlying implementation. This is a good reminder that the size of the input matters, and you should motivate your optimisations based on realistic data. +NB: most of these differences arise because `x` is small. If you increase the size the differences basically disappear, because most of the time is now spent computing the mean, not finding the underlying implementation. This is a good reminder that the size of the input matters, and you should motivate your optimisations based on realistic data. ```{r} x <- runif(1e4) diff --git a/Quotation.Rmd b/Quotation.Rmd index 31675f164..0d93447b4 100644 --- a/Quotation.Rmd +++ b/Quotation.Rmd @@ -1136,7 +1136,7 @@ new_function( ) ``` -NB: The empty arguments in `exprs()` generates arguments with no defaults. +NB: the empty arguments in `exprs()` generates arguments with no defaults. One use of `new_function()` is as an alternative to function factories with scalar or symbol arguments. For example, we could write a function that generates functions that raise a function to the power of a number. diff --git a/README.md b/README.md index f39bfcb11..861dacd90 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ Book: * Inconsolata scaled (by fontspec) to match main font is 9.42pt. -* Preview at 100% matches physical size of book. Maximum diagram width is 11cm. +* Preview at 100% matches physical size of book. Maxiumum diagram width is 11cm. R Markdown diff --git a/Rcpp.Rmd b/Rcpp.Rmd index b56c68062..3124cc44e 100644 --- a/Rcpp.Rmd +++ b/Rcpp.Rmd @@ -342,7 +342,7 @@ bench::mark( */ ``` -NB: If you run this code, you'll notice that `meanC()` is much faster than the built-in `mean()`. This is because it trades numerical accuracy for speed. +NB: if you run this code, you'll notice that `meanC()` is much faster than the built-in `mean()`. This is because it trades numerical accuracy for speed. For the remainder of this chapter, C++ code will be presented stand-alone rather than wrapped in a call to `cppFunction`. If you want to try compiling and/or modifying the examples, you should paste them into a C++ source file that includes the elements described above. This is easy to do in R Markdown: all you need to do is specifying the right [knitr language engine chunk option](https://yihui.org/knitr/options/#language-engines): diff --git a/S4.Rmd b/S4.Rmd index 916aeba4e..41f410adf 100644 --- a/S4.Rmd +++ b/S4.Rmd @@ -517,7 +517,7 @@ knitr::include_graphics("diagrams/s4/multiple.png") The basic process remains the same: you start from the actual class supplied to the generic, then follow the arrows until you find a defined method. The wrinkle is that now there are multiple arrows to follow, so you might find multiple methods. If that happens, you pick the method that is closest, i.e. requires travelling the fewest arrows. -NB: While the method graph is a powerful metaphor for understanding method dispatch, implementing it in this way would be rather inefficient, so the actual approach that S4 uses is somewhat different. You can read the details in `?Methods_Details`. +NB: while the method graph is a powerful metaphor for understanding method dispatch, implementing it in this way would be rather inefficient, so the actual approach that S4 uses is somewhat different. You can read the details in `?Methods_Details`. What happens if methods are the same distance? For example, imagine we've defined methods for `r emoji("dark_sunglasses")` and `r emoji("slightly_smiling_face")`, and we call the generic with `r emoji("sunglasses")`. Note that no method can be found for the `r emoji("no_mouth")` class, which I'll highlight with a red double outline.