Small copy edits edits to program.Rmd and pipes.Rmd

This commit is contained in:
Garrett 2016-04-07 16:54:53 -04:00
parent b724f667bb
commit 98f85a34d6
2 changed files with 18 additions and 19 deletions

View File

@ -5,11 +5,11 @@ library(dplyr)
diamonds <- ggplot2::diamonds
```
Pipes let you transform the way you call deeply nested functions. Using a pipe doesn't affect what the code does; behind the scenes it is run in (almost) exactly the same way. What the pipe does is change how you write, and read, code.
Pipes let you transform the way you call deeply nested functions. Using a pipe doesn't affect what the code does; behind the scenes it is run in (almost) the exact same way. What the pipe does is change how _you_ write, and read, code.
You've been using the pipe for a while now, so you already understand the basics. The point of this chapter is to explore the pipe in more detail. You'll learn the alternatives that the pipe replaces, and the pros and cons of the pipe. Importantly, you'll also learn situations in which you should avoid the pipe.
The pipe, `%>%`, comes from the magrittr package by Stefan Milton Bache. This package provides a handful of other helpful tools if you explicitly load it. We'll explore some of those tools to close out the chapter.
The pipe, `%>%`, comes from the __magrittr__ package by Stefan Milton Bache. This package provides a handful of other helpful tools if you explicitly load it. We'll explore some of those tools to close out the chapter.
## Piping alternatives
@ -33,7 +33,7 @@ And we'll use a function for each key verb: `hop()`, `scoop()`, and `bop()`. Usi
1. Compose functions.
1. Use the pipe.
We'll work through each approach, showing you the code and talking about the advantages and disadvantages.
We'll work through each approach, showing you the code and talking about the advantages and disadvantages. Note that these are made up functions; please don't expect this code to do something.
### Intermediate steps
@ -45,9 +45,9 @@ foo_foo_2 <- scoop(foo_foo_1, up = field_mice)
foo_foo_3 <- bop(foo_foo_2, on = head)
```
The main downside of this form is that it forces you to name each intermediate element. If there are natural names, this form feels natural, and you should use it. But in this example, there aren't natural names, and we're adding numeric suffixes just to make the names unique. That leads to two problems: the code is cluttered with unimportant names, and you have to be carefully increment the suffix on each line. Whenever I write code like this, I invariably use the wrong number on one line and then spend 10 minutes scratching my head and trying to figure out what went wrong with my code.
The main downside of this form is that it forces you to name each intermediate element. If there are natural names, this form feels natural, and you should use it. But in this example, there aren't natural names, and we're adding numeric suffixes just to make the names unique. That leads to two problems: the code is cluttered with unimportant names, and you have to carefully increment the suffix on each line. Whenever I write code like this, I invariably use the wrong number on one line and then spend 10 minutes scratching my head and trying to figure out what went wrong with my code.
You may worry that this form creates many intermediate copies of your data and takes up a lot of memory. First, worrying about memory is not a useful way to spend your time: worry about it when it becomes a problem (i.e. you run out of memory), not before. Second, R isn't stupid: if you're working with data frames, R will share columns where possible. Let's take a look at an actual data manipulation pipeline where we add a new column to the `diamonds` dataset from ggplot2:
You may worry that this form creates many intermediate copies of your data and takes up a lot of memory, but that's not necessary. First, worrying about memory is not a useful way to spend your time: worry about it when it becomes a problem (i.e. you run out of memory), not before. Second, R isn't stupid: if you're working with data frames, R will share columns where possible. Let's take a look at an actual data manipulation pipeline where we add a new column to the `diamonds` dataset from ggplot2:
```{r}
diamonds2 <- mutate(diamonds, price_per_carat = price / carat)
@ -110,7 +110,7 @@ bop(
```
Here the disadvantage is that you have to read from inside-out, from right-to-left, and that the arguments end up spread far apart (evocatively called the
[dagwood sandwhich](https://en.wikipedia.org/wiki/Dagwood_sandwich) problem).
[dagwood sandwhich](https://en.wikipedia.org/wiki/Dagwood_sandwich) problem). In short, this code is hard for a human to consume.
### Use the pipe
@ -161,10 +161,9 @@ This means that the pipe won't work for two classes of functions:
Other functions with this problem include `get()` and `load()`
1. Functions that make use lazy evaluation. In R, function arguments
1. Functions that use lazy evaluation. In R, function arguments
are only computed when the function uses them, not prior to calling the
function. This means that the function can affect the global environment in
various ways. The pipe computed each element in turn, so you can't
function. The pipe computes each element in turn, so you can't
rely on this behaviour.
One place that this is a problem is `tryCatch()`, which lets you capture
@ -201,13 +200,13 @@ The pipe is a powerful tool, but it's not the only tool at your disposal, and it
## Other tools from magrittr
The pipe is provided by the magrittr package, by Stefan Milton Bache. Most of packages you work in this book automatically provide `%>%` for you. You might want to load magrittr yourself if you're using another package, or you want to access some of the other pipe variants that magrittr provides.
The pipe is provided by the magrittr package, by Stefan Milton Bache. Most of the packages you work with in this book will automatically provide `%>%` for you. You might want to load magrittr yourself if you're using another package, or you want to access some of the other pipe variants that magrittr provides.
```{r}
library(magrittr)
```
* When working with more complex pipes, it's some times useful to call a
* When working with more complex pipes, it's sometimes useful to call a
function for its side-effects. Maybe you want to print out the current
object, or plot it, or save it to disk. Many times, such functions don't
return anything, effectively terminating the pipe.

View File

@ -2,21 +2,21 @@
Code is a tool of communication, not just to the computer, but to other people. This is important because every project you undertake is fundamentally collaborative. Even if you're not working with other people, you'll definitely be working with future-you. You want to write clear code so that future-you doesn't curse present-you when you look at a project again after several months have passed.
To me, improving your communication skills is a key part of mastering R as a programming language. Over time, you want your code to become more and more clear, and easier to write. Removing duplication is an important part of expressing yourself clearly because it lets the reader (i.e. future-you!) focus on what's different between operations rather than what's the same. The goal is not just to write better functions or to do things that you couldn't do before, but to code with more "ease". As you internalise the ideas in this chapter, you should find it easier to re-tackle problems that you've solved in the past with much effort.
To me, improving your communication skills is a key part of mastering R as a programming language. Over time, you want your code to become more and more clear, and easier to write. Removing duplication is an important part of expressing yourself clearly because it lets the reader (i.e. future-you!) focus on what's different between operations rather than what's the same. The goal is not just to write better functions or to do things that you couldn't do before, but to code with more "ease". As you internalise the ideas in this chapter, you should find it easier to re-tackle problems that you've struggled to solve in the past.
In the following chapters, you'll learn important programming skills:
1. We'll start by diving deep into the __pipe__, `%>%`, talking more about how
it works, what the alternatives are, and when not to use the pipe.
1. Copy-and-paste is powerful tool, but you should avoid doing it more than
1. Copy-and-paste is a powerful tool, but you should avoid doing it more than
twice. Repeating yourself in code is dangerous because it can easily lead
to errors and inconsistencies. Instead, write __functions__ which let
you extract out repeated code so that it can be easily reused.
1. Functions extract out repeated code, but you often need to repeat the
same actions on multiple inputs. You need tools for __iteration__ that
let you do similar things again again. These tools include for loops
let you do similar things again and again. These tools include for loops
and functional programming.
1. As you start to write more powerful functions, you'll need a solid
@ -24,16 +24,16 @@ In the following chapters, you'll learn important programming skills:
vectors, the three important S3 classes built on top of them, and
understand the mysteries of the list and data frame.
1. One of the partiuclarly important data structures in R is the list.
Lists are important because a list can contain other lists, so is
1. One of the particularly important data structures in R is the list.
Lists are important because a list can contain other lists, so it is
__hierarchical__. Two common scenarios where hierarchical structures
arise are json, and fitting many models. You'll need to learn some new
tools from the purrr package to make handling these cases as easy as
tools from the purrr package to make handle these cases as easily as
possible.
The goal of these chapters is to teach you the minimum about programming that a practicising data scientist must know. It turns out this is a reasonable amount, and I think it's worth investing in your programming skills. It's an investment that won't pay off immediately, but over time it will allow you to solve new problems more quickly, and reuse your insights from previous problems in new scenarios.
Writing code is similar in many ways to writing prose. One parallel which I find particularly useful is that in both cases rewriting is key to clarity. The first expression of your ideas is unlikely to be particularly clear, and you may need to rewrite multiple times. After solving a data analysis challenge, it's often worth looking at your code and thinking about whether or not it's obvious what you've done. If you spend a little time rewriting your code while the ideas are fresh, you can save a lot of time later trying to recreate what your code did. But this doesn't mean you should rewrite every function: you need to balance what you need to achieve now with saving time in the long run. (But the more you rewrite your functions the more likely you'll first attempt will be clear.)
Writing code is similar in many ways to writing prose. One parallel which I find particularly useful is that in both cases rewriting is the key to clarity. The first expression of your ideas is unlikely to be particularly clear, and you may need to rewrite multiple times. After solving a data analysis challenge, it's often worth looking at your code and thinking about whether or not it's obvious what you've done. If you spend a little time rewriting your code while the ideas are fresh, you can save a lot of time later trying to recreate what your code did. But this doesn't mean you should rewrite every function: you need to balance what you need to achieve now with saving time in the long run. (But the more you rewrite your functions the more likely you'll first attempt will be clear.)
## Learning more
@ -41,7 +41,7 @@ As you become a better R programmer, you'll learn more techniques for reducing v
To learn more you need to study R as a programming language, not just an interactive environment for data science. We have written two books that will help you do so:
* [Hands on programming with R](http://shop.oreilly.com/product/0636920028574.do),
* [Hands on Programming with R](http://shop.oreilly.com/product/0636920028574.do),
by Garrett Grolemund. This is an introduction to R as a programming language
and is a great place to start if R is your first programming language.