Hadley Wickham, Mine Çetinkaya-Rundel & Garrett Grolemund R for Data Science Import, Tidy, Transform, Visualize, and Model Data Second Edition
DATA “This is an astonishingly good update to a world-leading guide to doing data science with R. Everyone who works with data should read it!” —Emma Rand University of York, UK R for Data Science Twitter: @oreillymedia linkedin.com/company/oreilly-media youtube.com/oreillymedia Use R to turn data into insight, knowledge, and understanding. With this practical book, aspiring data scientists will learn how to do data science with R and RStudio, along with the tidyverse—a collection of R packages designed to work together to make data science fast, fluent, and fun. Even if you have no programming experience, this updated edition will have you doing data science quickly. You’ll learn how to import, transform, and visualize your data and communicate the results. And you’ll get a complete, big-picture understanding of the data science cycle and the basic tools you need to manage the details. Updated for the latest tidyverse features and best practices, new chapters show you how to get data from spreadsheets, databases, and websites. Exercises help you practice what you’ve learned along the way. You’ll understand how to: • Visualize: Create plots for data exploration and communication of results • Transform: Discover variable types and the tools to work with them • Import: Get data into R and in a form convenient for analysis • Program: Learn R tools for solving data problems with greater clarity and ease • Communicate: Integrate prose, code, and results with Quarto Hadley Wickham is chief scientist at Posit and a member of the R Foundation. He builds computational and cognitive tools that make data science easier, faster, and more fun. Mine Çetinkaya-Rundel is professor of the practice and director of undergraduate studies at the Department of Statistical Science at Duke University. She’s also a developer educator at Posit. Garrett Grolemund is the author of Hands-On Programming with R and director of learning at Posit. US $79.99 CAN $99.99 ISBN: 978-1-492-09740-2
Hadley Wickham, Mine Çetinkaya-Rundel, and Garrett Grolemund R for Data Science Import, Tidy, Transform, Visualize, and Model Data 2ND EDITION Boston Farnham Sebastopol TokyoBeijing
978-1-492-09740-2 [LSI] R for Data Science by Hadley Wickham, Mine Çetinkaya-Rundel, and Garrett Grolemund Copyright © 2023 Hadley Wickham, Mine Çetinkaya-Rundel, and Garrett Grolemund. All rights reserved. Printed in the United States of America. Published by O’Reilly Media, Inc., 1005 Gravenstein Highway North, Sebastopol, CA 95472. O’Reilly books may be purchased for educational, business, or sales promotional use. Online editions are also available for most titles (http://oreilly.com). For more information, contact our corporate/institutional sales department: 800-998-9938 or corporate@oreilly.com. Acquisitions Editor: Aaron Black Development Editor: Melissa Potter Production Editor: Ashley Stussy Copyeditor: Kim Wimpsett Proofreader: Charles Roumeliotis Indexer: WordCo Indexing Services, Inc. Interior Designer: David Futato Cover Designer: Karen Montgomery Illustrator: Kate Dullea June 2023: First Edition Revision History for the Second Edition 2023-06-07: First Release See http://oreilly.com/catalog/errata.csp?isbn=9781492097402 for release details. The O’Reilly logo is a registered trademark of O’Reilly Media, Inc. R for Data Science, the cover image, and related trade dress are trademarks of O’Reilly Media, Inc. The views expressed in this work are those of the authors and do not represent the publisher’s views. While the publisher and the authors have used good faith efforts to ensure that the information and instructions contained in this work are accurate, the publisher and the authors disclaim all responsibility for errors or omissions, including without limitation responsibility for damages resulting from the use of or reliance on this work. Use of the information and instructions contained in this work is at your own risk. If any code samples or other technology this work contains or describes is subject to open source licenses or the intellectual property rights of others, it is your responsibility to ensure that your use thereof complies with such licenses and/or rights.
Table of Contents Introduction. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xi Part I. Whole Game 1. Data Visualization. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 Introduction 3 First Steps 4 ggplot2 Calls 16 Visualizing Distributions 16 Visualizing Relationships 21 Saving Your Plots 30 Common Problems 30 Summary 31 2. Workflow: Basics. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33 Coding Basics 33 Comments 34 What’s in a Name? 35 Calling Functions 36 Exercises 37 Summary 37 3. Data Transformation. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39 Introduction 39 Rows 42 Columns 47 The Pipe 51 iii
Groups 53 Case Study: Aggregates and Sample Size 60 Summary 62 4. Workflow: Code Style. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63 Names 64 Spaces 65 Pipes 65 ggplot2 67 Sectioning Comments 67 Exercises 68 Summary 68 5. Data Tidying. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69 Introduction 69 Tidy Data 70 Lengthening Data 73 Widening Data 81 Summary 85 6. Workflow: Scripts and Projects. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87 Scripts 87 Projects 91 Exercises 96 Summary 96 7. Data Import. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97 Introduction 97 Reading Data from a File 97 Controlling Column Types 104 Reading Data from Multiple Files 107 Writing to a File 108 Data Entry 109 Summary 110 8. Workflow: Getting Help. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111 Google Is Your Friend 111 Making a reprex 111 Investing in Yourself 113 Summary 114 iv | Table of Contents
Part II. Visualize 9. Layers. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117 Introduction 117 Aesthetic Mappings 118 Geometric Objects 122 Facets 128 Statistical Transformations 131 Position Adjustments 136 Coordinate Systems 141 The Layered Grammar of Graphics 143 Summary 144 10. Exploratory Data Analysis. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145 Introduction 145 Questions 146 Variation 146 Unusual Values 151 Covariation 154 Patterns and Models 164 Summary 167 11. Communication. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 169 Introduction 169 Labels 170 Annotations 172 Scales 177 Themes 193 Layout 196 Summary 201 Part III. Transform 12. Logical Vectors. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 205 Introduction 205 Comparisons 206 Boolean Algebra 210 Summaries 213 Conditional Transformations 216 Summary 219 Table of Contents | v
13. Numbers. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 221 Introduction 221 Making Numbers 221 Counts 222 Numeric Transformations 224 General Transformations 231 Numeric Summaries 235 Summary 241 14. Strings. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 243 Introduction 243 Creating a String 244 Creating Many Strings from Data 246 Extracting Data from Strings 249 Letters 254 Non-English Text 256 Summary 259 15. Regular Expressions. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 261 Introduction 261 Pattern Basics 262 Key Functions 264 Pattern Details 268 Pattern Control 275 Practice 277 Regular Expressions in Other Places 282 Summary 283 16. Factors. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 285 Introduction 285 Factor Basics 285 General Social Survey 287 Modifying Factor Order 288 Modifying Factor Levels 293 Ordered Factors 295 Summary 296 17. Dates and Times. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 297 Introduction 297 Creating Date/Times 298 Date-Time Components 305 Time Spans 313 vi | Table of Contents
Time Zones 317 Summary 319 18. Missing Values. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 321 Introduction 321 Explicit Missing Values 321 Implicit Missing Values 323 Factors and Empty Groups 326 Summary 328 19. Joins. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 329 Introduction 329 Keys 330 Basic Joins 334 How Do Joins Work? 341 Non-Equi Joins 346 Summary 353 Part IV. Import 20. Spreadsheets. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 357 Introduction 357 Excel 357 Google Sheets 371 Summary 375 21. Databases. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 377 Introduction 377 Database Basics 378 Connecting to a Database 378 dbplyr Basics 381 SQL 383 Function Translations 391 Summary 394 22. Arrow. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 395 Introduction 395 Getting the Data 396 Opening a Dataset 396 The Parquet Format 398 Using dplyr with Arrow 400 Table of Contents | vii
Summary 402 23. Hierarchical Data. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 403 Introduction 403 Lists 404 Unnesting 408 Case Studies 412 JSON 420 Summary 423 24. Web Scraping. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 425 Introduction 425 Scraping Ethics and Legalities 426 HTML Basics 427 Extracting Data 429 Finding the Right Selectors 433 Putting It All Together 434 Dynamic Sites 439 Summary 440 Part V. Program 25. Functions. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 443 Introduction 443 Vector Functions 444 Data Frame Functions 449 Plot Functions 456 Style 463 Summary 464 26. Iteration. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 465 Introduction 465 Modifying Multiple Columns 466 Reading Multiple Files 475 Saving Multiple Outputs 483 Summary 488 27. A Field Guide to Base R. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 489 Introduction 489 Selecting Multiple Elements with [ 490 Selecting a Single Element with $ and [[ 494 viii | Table of Contents
Apply Family 497 for Loops 499 Plots 500 Summary 501 Part VI. Communicate 28. Quarto. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 505 Introduction 505 Quarto Basics 506 Visual Editor 509 Source Editor 511 Code Chunks 513 Figures 517 Tables 521 Caching 522 Troubleshooting 523 YAML Header 524 Workflow 527 Summary 528 29. Quarto Formats. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 531 Introduction 531 Output Options 531 Documents 532 Presentations 533 Interactivity 533 Websites and Books 536 Other Formats 537 Summary 537 Index. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 539 Table of Contents | ix
(This page has no text content)
Introduction Data science is an exciting discipline that allows you to transform raw data into understanding, insight, and knowledge. The goals of R for Data Science are to help you learn the most important tools in R that will allow you to do data science efficiently and reproducibly and to have some fun along the way! After reading this book, you’ll have the tools to tackle a wide variety of data science challenges using the best parts of R. Preface to the Second Edition Welcome to the second edition of R for Data Science (R4DS)! This is a major rework‐ ing of the first edition, removing material we no longer think is useful, adding material we wish we included in the first edition, and generally updating the text and code to reflect changes in best practices. We’re also very excited to welcome a new co-author: Mine Çetinkaya-Rundel, a noted data science educator and one of our colleagues at Posit (the company formerly known as RStudio). A brief summary of the biggest changes follows: • The first part of the book has been renamed to “Whole Game.” The goal of this section is to give you the rough details of the “whole game” of data science before we dive into the details. • The second part of the book is “Visualize.” This part gives data visualization tools and best practices a more thorough coverage compared to the first edition. The best place to get all the details is still the ggplot2 book, but now R4DS covers more of the most important techniques. • The third part of the book is now called “Transform” and gains new chapters on numbers, logical vectors, and missing values. These were previously parts of the data transformation chapter but needed much more room to cover all the details. xi
• The fourth part of the book is called “Import.” It’s a new set of chapters that goes beyond reading flat text files to working with spreadsheets, getting data out of databases, working with big data, rectangling hierarchical data, and scraping data from websites. • The “Program” part remains but has been rewritten from top to bottom to focus on the most important parts of function writing and iteration. Function writing now includes details on how to wrap tidyverse functions (dealing with the challenges of tidy evaluation), since this has become much easier and more important over the last few years. We’ve added a new chapter on important base R functions that you’re likely to see in wild-caught R code. • The “Modeling” part has been removed. We never had enough room to fully do modeling justice, and there are now much better resources available. We generally recommend using the tidymodels packages and reading Tidy Modeling with R by Max Kuhn and Julia Silge (O’Reilly). • The “Communicate” part remains but has been thoroughly updated to feature Quarto instead of R Markdown. This edition of the book has been written in Quarto, and it’s clearly the tool of the future. What You Will Learn Data science is a vast field, and there’s no way you can master it all by reading a single book. This book aims to give you a solid foundation in the most important tools and enough knowledge to find the resources to learn more when necessary. Our model of the steps of a typical data science project looks something like Figure I-1. Figure I-1. In our model of the data science process, you start with data import and tidy‐ ing. Next, you understand your data with an iterative cycle of transforming, visualizing, and modeling. You finish the process by communicating your results to other humans. First, you must import your data into R. This typically means that you take data stored in a file, database, or web application programming interface (API) and load xii | Introduction
it into a data frame in R. If you can’t get your data into R, you can’t do data science on it! Once you’ve imported your data, it is a good idea to tidy it. Tidying your data means storing it in a consistent form that matches the semantics of the dataset with how it is stored. In brief, when your data is tidy, each column is a variable and each row is an observation. Tidy data is important because the consistent structure lets you focus your efforts on answering questions about the data, not fighting to get the data into the right form for different functions. Once you have tidy data, a common next step is to transform it. Transformation includes narrowing in on observations of interest (such as all people in one city or all data from the last year), creating new variables that are functions of existing variables (such as computing speed from distance and time), and calculating a set of summary statistics (such as counts or means). Together, tidying and transforming are called wrangling because getting your data in a form that’s natural to work with often feels like a fight! Once you have tidy data with the variables you need, there are two main engines of knowledge generation: visualization and modeling. They have complementary strengths and weaknesses, so any real data analysis will iterate between them many times. Visualization is a fundamentally human activity. A good visualization will show you things you did not expect or raise new questions about the data. A good visualization might also hint that you’re asking the wrong question or that you need to collect different data. Visualizations can surprise you, but they don’t scale particularly well because they require a human to interpret them. Models are complementary tools to visualization. Once you have made your questions sufficiently precise, you can use a model to answer them. Models are fundamentally mathematical or computational tools, so they generally scale well. Even when they don’t, it’s usually cheaper to buy more computers than it is to buy more brains! But every model makes assumptions, and by its very nature a model cannot question its own assumptions. That means a model cannot fundamentally surprise you. The last step of data science is communication, an absolutely critical part of any data analysis project. It doesn’t matter how well your models and visualization have led you to understand the data unless you can also communicate your results to others. Surrounding all these tools is programming. Programming is a cross-cutting tool that you use in nearly every part of a data science project. You don’t need to be an expert programmer to be a successful data scientist, but learning more about programming pays off because becoming a better programmer allows you to automate common tasks and solve new problems with greater ease. Introduction | xiii
You’ll use these tools in every data science project, but they’re not enough for most projects. There’s a rough 80/20 rule at play: you can tackle about 80% of every project using the tools you’ll learn in this book, but you’ll need other tools to tackle the remaining 20%. Throughout this book, we’ll point you to resources where you can learn more. How This Book Is Organized The previous description of the tools of data science is organized roughly according to the order in which you use them in an analysis (although, of course, you’ll iterate through them multiple times). In our experience, however, learning data importing and tidying first is suboptimal because, 80% of the time, it’s routine and boring, and the other 20% of the time, it’s weird and frustrating. That’s a bad place to start learning a new subject! Instead, we’ll start with visualization and transformation of data that’s already been imported and tidied. That way, when you ingest and tidy your own data, your motivation will stay high because you know the pain is worth the effort. Within each chapter, we try to adhere to a consistent pattern: start with some moti‐ vating examples so you can see the bigger picture and then dive into the details. Each section of the book is paired with exercises to help you practice what you’ve learned. Although it can be tempting to skip the exercises, there’s no better way to learn than by practicing on real problems. What You Won’t Learn There are several important topics that this book doesn’t cover. We believe it’s impor‐ tant to stay ruthlessly focused on the essentials so you can get up and running as quickly as possible. That means this book can’t cover every important topic. Modeling Modeling is super important for data science, but it’s a big topic, and unfortunately, we just don’t have the space to give it the coverage it deserves here. To learn more about modeling, we highly recommend Tidy Modeling with R by our colleagues Max Kuhn and Julia Silge (O’Reilly). This book will teach you the tidymodels family of packages, which, as you might guess from the name, share many conventions with the tidyverse packages we use in this book. Big Data This book proudly and primarily focuses on small, in-memory datasets. This is the right place to start because you can’t tackle big data unless you have experience with small data. The tools you learn in the majority of this book will easily handle xiv | Introduction
hundreds of megabytes of data, and with a bit of care, you can typically use them to work with a few gigabytes of data. We’ll also show you how to get data out of databases and parquet files, both of which are often used to store big data. You won’t necessarily be able to work with the entire dataset, but that’s not a problem because you need only a subset or subsample to answer the question you’re interested in. If you’re routinely working with larger data (10–100 GB, say), we recommend learn‐ ing more about data.table. We don’t teach it here because it uses a different interface than the tidyverse and requires you to learn some different conventions. However, it is incredibly faster, and the performance payoff is worth investing some time in learning it if you’re working with large data. Python, Julia, and Friends In this book, you won’t learn anything about Python, Julia, or any other program‐ ming language useful for data science. This isn’t because we think these tools are bad. They’re not! And in practice, most data science teams use a mix of languages, often at least R and Python. But we strongly believe that it’s best to master one tool at a time, and R is a great place to start. Prerequisites We’ve made a few assumptions about what you already know to get the most out of this book. You should be generally numerically literate, and it’s helpful if you have some basic programming experience already. If you’ve never programmed before, you might find Hands-On Programming with R by Garrett Grolemund (O’Reilly) to be a valuable adjunct to this book. You need four things to run the code in this book: R, RStudio, a collection of R packages called the tidyverse, and a handful of other packages. Packages are the fundamental units of reproducible R code. They include reusable functions, docu‐ mentation that describes how to use them, and sample data. Introduction | xv
1 If you’d like a comprehensive overview of all of RStudio’s features, see the RStudio User Guide. R To download R, go to CRAN, the comprehensive R archive network. A new major version of R comes out once a year, and there are two to three minor releases each year. It’s a good idea to update regularly. Upgrading can be a bit of a hassle, especially for major versions that require you to re-install all your packages, but putting it off only makes it worse. We recommend R 4.2.0 or later for this book. RStudio RStudio is an integrated development environment (IDE) for R programming, which you can download from the RStudio download page. RStudio is updated a couple of times a year, and it will automatically let you know when a new version is out, so there’s no need to check back. It’s a good idea to upgrade regularly to take advantage of the latest and greatest features. For this book, make sure you have at least RStudio 2022.02.0. When you start RStudio, Figure I-2, you’ll see two key regions in the interface: the console pane and the output pane. For now, all you need to know is that you type the R code in the console pane and press Enter to run it. You’ll learn more as we go along!1 xvi | Introduction
Figure I-2. The RStudio IDE has two key regions: type R code in the console pane on the left, and look for plots in the output pane on the right. The Tidyverse You’ll also need to install some R packages. An R package is a collection of functions, data, and documentation that extends the capabilities of base R. Using packages is key to the successful use of R. The majority of the packages that you will learn in this book are part of the so-called tidyverse. All packages in the tidyverse share a common philosophy of data and R programming and are designed to work together. You can install the complete tidyverse with a single line of code: install.packages("tidyverse") On your computer, type that line of code in the console, and then press Enter to run it. R will download the packages from CRAN and install them on your computer. You will not be able to use the functions, objects, or help files in a package until you load it. Once you have installed a package, you can load it using the library() function: Introduction | xvii
library(tidyverse) #> ── Attaching core tidyverse packages ───────────────────── tidyverse 2.0.0 ── #> ✔ dplyr 1.1.0.9000 ✔ readr 2.1.4 #> ✔ forcats 1.0.0 ✔ stringr 1.5.0 #> ✔ ggplot2 3.4.1 ✔ tibble 3.1.8 #> ✔ lubridate 1.9.2 ✔ tidyr 1.3.0 #> ✔ purrr 1.0.1 #> ── Conflicts ─────────────────────────────────────── tidyverse_conflicts() ── #> ✖ dplyr::filter() masks stats::filter() #> ✖ dplyr::lag() masks stats::lag() #> ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all #> conflicts to become errors This tells you that tidyverse loads nine packages: dplyr, forcats, ggplot2, lubridate, purrr, readr, stringr, tibble, and tidyr. These are considered the core of the tidyverse because you’ll use them in almost every analysis. Packages in the tidyverse change fairly frequently. You can see if updates are available by running tidyverse_update(). Other Packages There are many other excellent packages that are not part of the tidyverse because they solve problems in a different domain or are designed with a different set of underlying principles. This doesn’t make them better or worse; it just makes them different. In other words, the complement to the tidyverse is not the messyverse but many other universes of interrelated packages. As you tackle more data science projects with R, you’ll learn new packages and new ways of thinking about data. We’ll use many packages from outside the tidyverse in this book. For example, we’ll use the following packages because they provide interesting data sets for us to work with in the process of learning R: install.packages(c("arrow", "babynames", "curl", "duckdb", "gapminder", "ggrepel", "ggridges", "ggthemes", "hexbin", "janitor", "Lahman", "leaflet", "maps", "nycflights13", "openxlsx", "palmerpenguins", "repurrrsive", "tidymodels", "writexl")) We’ll also use a selection of other packages for one-off examples. You don’t need to install them now, just remember that whenever you see an error like this: library(ggrepel) #> Error in library(ggrepel) : there is no package called ‘ggrepel’ it means you need to run install.packages("ggrepel") to install the package. Running R Code The previous section showed you several examples of running R code. The code in the book looks like this: 1 + 2 #> [1] 3 xviii | Introduction
Comments 0
Loading comments...
Reply to Comment
Edit Comment