CINXE.COM
2 Workflow: basics – R for Data Science (2e)
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <meta charset="utf-8"> <meta name="generator" content="quarto-1.6.41"> <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes"> <meta name="author" content="Hadley Wickham, Mine Çetinkaya-Rundel, and Garrett Grolemund"> <title>2 Workflow: basics – R for Data Science (2e)</title> <style> code{white-space: pre-wrap;} span.smallcaps{font-variant: small-caps;} div.columns{display: flex; gap: min(4vw, 1.5em);} div.column{flex: auto; overflow-x: auto;} div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;} ul.task-list{list-style: none;} ul.task-list li input[type="checkbox"] { width: 0.8em; margin: 0 0.8em 0.2em -1em; /* quarto-specific, see https://github.com/quarto-dev/quarto-cli/issues/4556 */ vertical-align: middle; } /* CSS for syntax highlighting */ pre > code.sourceCode { white-space: pre; position: relative; } pre > code.sourceCode > span { line-height: 1.25; } pre > code.sourceCode > span:empty { height: 1.2em; } .sourceCode { overflow: visible; } code.sourceCode > span { color: inherit; text-decoration: inherit; } div.sourceCode { margin: 1em 0; } pre.sourceCode { margin: 0; } @media screen { div.sourceCode { overflow: auto; } } @media print { pre > code.sourceCode { white-space: pre-wrap; } pre > code.sourceCode > span { display: inline-block; text-indent: -5em; padding-left: 5em; } } pre.numberSource code { counter-reset: source-line 0; } pre.numberSource code > span { position: relative; left: -4em; counter-increment: source-line; } pre.numberSource code > span > a:first-child::before { content: counter(source-line); position: relative; left: -1em; text-align: right; vertical-align: baseline; border: none; display: inline-block; -webkit-touch-callout: none; -webkit-user-select: none; -khtml-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; padding: 0 4px; width: 4em; } pre.numberSource { margin-left: 3em; padding-left: 4px; } div.sourceCode { } @media screen { pre > code.sourceCode > span > a:first-child::before { text-decoration: underline; } } </style> <script src="site_libs/quarto-nav/quarto-nav.js"></script> <script src="site_libs/quarto-nav/headroom.min.js"></script> <script src="site_libs/clipboard/clipboard.min.js"></script> <script src="site_libs/quarto-search/autocomplete.umd.js"></script> <script src="site_libs/quarto-search/fuse.min.js"></script> <script src="site_libs/quarto-search/quarto-search.js"></script> <meta name="quarto:offset" content="./"> <link href="./data-transform.html" rel="next"> <link href="./data-visualize.html" rel="prev"> <link href="./cover.jpg" rel="icon" type="image/jpeg"> <script src="site_libs/quarto-html/quarto.js"></script> <script src="site_libs/quarto-html/popper.min.js"></script> <script src="site_libs/quarto-html/tippy.umd.min.js"></script> <script src="site_libs/quarto-html/anchor.min.js"></script> <link href="site_libs/quarto-html/tippy.css" rel="stylesheet"> <link href="site_libs/quarto-html/quarto-syntax-highlighting-48ffa3e5b9d089919c6712c39e5b00f2.css" rel="stylesheet" id="quarto-text-highlighting-styles"> <script src="site_libs/bootstrap/bootstrap.min.js"></script> <link href="site_libs/bootstrap/bootstrap-icons.css" rel="stylesheet"> <link href="site_libs/bootstrap/bootstrap-8ce0fe0cac6e1f664755c487f6c42e13.min.css" rel="stylesheet" append-hash="true" id="quarto-bootstrap" data-mode="light"><script id="quarto-search-options" type="application/json">{ "location": "sidebar", "copy-button": false, "collapse-after": 3, "panel-placement": "start", "type": "textbox", "limit": 50, "keyboard-shortcut": [ "f", "/", "s" ], "show-item-context": false, "language": { "search-no-results-text": "No results", "search-matching-documents-text": "matching documents", "search-copy-link-title": "Copy link to search", "search-hide-matches-text": "Hide additional matches", "search-more-match-text": "more match in this document", "search-more-matches-text": "more matches in this document", "search-clear-button-title": "Clear", "search-text-placeholder": "", "search-detached-cancel-button-title": "Cancel", "search-submit-button-title": "Submit", "search-label": "Search" } }</script><script defer="" data-domain="r4ds.hadley.nz" src="https://plausible.io/js/plausible.js"></script> </head> <body class="nav-sidebar floating"> <div id="quarto-search-results"></div> <header id="quarto-header" class="headroom fixed-top"><nav class="quarto-secondary-nav"><div class="container-fluid d-flex"> <button type="button" class="quarto-btn-toggle btn" data-bs-toggle="collapse" role="button" data-bs-target=".quarto-sidebar-collapse-item" aria-controls="quarto-sidebar" aria-expanded="false" aria-label="Toggle sidebar navigation" onclick="if (window.quartoToggleHeadroom) { window.quartoToggleHeadroom(); }"> <i class="bi bi-layout-text-sidebar-reverse"></i> </button> <nav class="quarto-page-breadcrumbs" aria-label="breadcrumb"><ol class="breadcrumb"><li class="breadcrumb-item"><a href="./whole-game.html">Whole game</a></li><li class="breadcrumb-item"><a href="./workflow-basics.html"><span class="chapter-number">2</span> <span class="chapter-title">Workflow: basics</span></a></li></ol></nav> <a class="flex-grow-1" role="navigation" data-bs-toggle="collapse" data-bs-target=".quarto-sidebar-collapse-item" aria-controls="quarto-sidebar" aria-expanded="false" aria-label="Toggle sidebar navigation" onclick="if (window.quartoToggleHeadroom) { window.quartoToggleHeadroom(); }"> </a> <button type="button" class="btn quarto-search-button" aria-label="Search" onclick="window.quartoOpenSearch();"> <i class="bi bi-search"></i> </button> </div> </nav></header><!-- content --><div id="quarto-content" class="quarto-container page-columns page-rows-contents page-layout-article"> <!-- sidebar --> <nav id="quarto-sidebar" class="sidebar collapse collapse-horizontal quarto-sidebar-collapse-item sidebar-navigation floating overflow-auto"><div class="pt-lg-2 mt-2 text-left sidebar-header"> <div class="sidebar-title mb-0 py-0"> <a href="./">R for Data Science (2e)</a> <div class="sidebar-tools-main"> <a href="https://github.com/hadley/r4ds/" title="Source Code" class="quarto-navigation-tool px-1" aria-label="Source Code"><i class="bi bi-github"></i></a> <a href="" class="quarto-reader-toggle quarto-navigation-tool px-1" onclick="window.quartoToggleReader(); return false;" title="Toggle reader mode"> <div class="quarto-reader-toggle-btn"> <i class="bi"></i> </div> </a> </div> </div> </div> <div class="mt-2 flex-shrink-0 align-items-center"> <div class="sidebar-search"> <div id="quarto-search" class="" title="Search"></div> </div> </div> <div class="sidebar-menu-container"> <ul class="list-unstyled mt-1"> <li class="sidebar-item"> <div class="sidebar-item-container"> <a href="./index.html" class="sidebar-item-text sidebar-link"> <span class="menu-text">Welcome</span></a> </div> </li> <li class="sidebar-item"> <div class="sidebar-item-container"> <a href="./preface-2e.html" class="sidebar-item-text sidebar-link"> <span class="menu-text">Preface to the second edition</span></a> </div> </li> <li class="sidebar-item"> <div class="sidebar-item-container"> <a href="./intro.html" class="sidebar-item-text sidebar-link"> <span class="menu-text">Introduction</span></a> </div> </li> <li class="sidebar-item sidebar-item-section"> <div class="sidebar-item-container"> <a href="./whole-game.html" class="sidebar-item-text sidebar-link"> <span class="menu-text">Whole game</span></a> <a class="sidebar-item-toggle text-start" data-bs-toggle="collapse" data-bs-target="#quarto-sidebar-section-1" role="navigation" aria-expanded="true" aria-label="Toggle section"> <i class="bi bi-chevron-right ms-2"></i> </a> </div> <ul id="quarto-sidebar-section-1" class="collapse list-unstyled sidebar-section depth1 show"> <li class="sidebar-item"> <div class="sidebar-item-container"> <a href="./data-visualize.html" class="sidebar-item-text sidebar-link"> <span class="menu-text"><span class="chapter-number">1</span> <span class="chapter-title">Data visualization</span></span></a> </div> </li> <li class="sidebar-item"> <div class="sidebar-item-container"> <a href="./workflow-basics.html" class="sidebar-item-text sidebar-link active"> <span class="menu-text"><span class="chapter-number">2</span> <span class="chapter-title">Workflow: basics</span></span></a> </div> </li> <li class="sidebar-item"> <div class="sidebar-item-container"> <a href="./data-transform.html" class="sidebar-item-text sidebar-link"> <span class="menu-text"><span class="chapter-number">3</span> <span class="chapter-title">Data transformation</span></span></a> </div> </li> <li class="sidebar-item"> <div class="sidebar-item-container"> <a href="./workflow-style.html" class="sidebar-item-text sidebar-link"> <span class="menu-text"><span class="chapter-number">4</span> <span class="chapter-title">Workflow: code style</span></span></a> </div> </li> <li class="sidebar-item"> <div class="sidebar-item-container"> <a href="./data-tidy.html" class="sidebar-item-text sidebar-link"> <span class="menu-text"><span class="chapter-number">5</span> <span class="chapter-title">Data tidying</span></span></a> </div> </li> <li class="sidebar-item"> <div class="sidebar-item-container"> <a href="./workflow-scripts.html" class="sidebar-item-text sidebar-link"> <span class="menu-text"><span class="chapter-number">6</span> <span class="chapter-title">Workflow: scripts and projects</span></span></a> </div> </li> <li class="sidebar-item"> <div class="sidebar-item-container"> <a href="./data-import.html" class="sidebar-item-text sidebar-link"> <span class="menu-text"><span class="chapter-number">7</span> <span class="chapter-title">Data import</span></span></a> </div> </li> <li class="sidebar-item"> <div class="sidebar-item-container"> <a href="./workflow-help.html" class="sidebar-item-text sidebar-link"> <span class="menu-text"><span class="chapter-number">8</span> <span class="chapter-title">Workflow: getting help</span></span></a> </div> </li> </ul> </li> <li class="sidebar-item sidebar-item-section"> <div class="sidebar-item-container"> <a href="./visualize.html" class="sidebar-item-text sidebar-link"> <span class="menu-text">Visualize</span></a> <a class="sidebar-item-toggle text-start" data-bs-toggle="collapse" data-bs-target="#quarto-sidebar-section-2" role="navigation" aria-expanded="true" aria-label="Toggle section"> <i class="bi bi-chevron-right ms-2"></i> </a> </div> <ul id="quarto-sidebar-section-2" class="collapse list-unstyled sidebar-section depth1 show"> <li class="sidebar-item"> <div class="sidebar-item-container"> <a href="./layers.html" class="sidebar-item-text sidebar-link"> <span class="menu-text"><span class="chapter-number">9</span> <span class="chapter-title">Layers</span></span></a> </div> </li> <li class="sidebar-item"> <div class="sidebar-item-container"> <a href="./EDA.html" class="sidebar-item-text sidebar-link"> <span class="menu-text"><span class="chapter-number">10</span> <span class="chapter-title">Exploratory data analysis</span></span></a> </div> </li> <li class="sidebar-item"> <div class="sidebar-item-container"> <a href="./communication.html" class="sidebar-item-text sidebar-link"> <span class="menu-text"><span class="chapter-number">11</span> <span class="chapter-title">Communication</span></span></a> </div> </li> </ul> </li> <li class="sidebar-item sidebar-item-section"> <div class="sidebar-item-container"> <a href="./transform.html" class="sidebar-item-text sidebar-link"> <span class="menu-text">Transform</span></a> <a class="sidebar-item-toggle text-start" data-bs-toggle="collapse" data-bs-target="#quarto-sidebar-section-3" role="navigation" aria-expanded="true" aria-label="Toggle section"> <i class="bi bi-chevron-right ms-2"></i> </a> </div> <ul id="quarto-sidebar-section-3" class="collapse list-unstyled sidebar-section depth1 show"> <li class="sidebar-item"> <div class="sidebar-item-container"> <a href="./logicals.html" class="sidebar-item-text sidebar-link"> <span class="menu-text"><span class="chapter-number">12</span> <span class="chapter-title">Logical vectors</span></span></a> </div> </li> <li class="sidebar-item"> <div class="sidebar-item-container"> <a href="./numbers.html" class="sidebar-item-text sidebar-link"> <span class="menu-text"><span class="chapter-number">13</span> <span class="chapter-title">Numbers</span></span></a> </div> </li> <li class="sidebar-item"> <div class="sidebar-item-container"> <a href="./strings.html" class="sidebar-item-text sidebar-link"> <span class="menu-text"><span class="chapter-number">14</span> <span class="chapter-title">Strings</span></span></a> </div> </li> <li class="sidebar-item"> <div class="sidebar-item-container"> <a href="./regexps.html" class="sidebar-item-text sidebar-link"> <span class="menu-text"><span class="chapter-number">15</span> <span class="chapter-title">Regular expressions</span></span></a> </div> </li> <li class="sidebar-item"> <div class="sidebar-item-container"> <a href="./factors.html" class="sidebar-item-text sidebar-link"> <span class="menu-text"><span class="chapter-number">16</span> <span class="chapter-title">Factors</span></span></a> </div> </li> <li class="sidebar-item"> <div class="sidebar-item-container"> <a href="./datetimes.html" class="sidebar-item-text sidebar-link"> <span class="menu-text"><span class="chapter-number">17</span> <span class="chapter-title">Dates and times</span></span></a> </div> </li> <li class="sidebar-item"> <div class="sidebar-item-container"> <a href="./missing-values.html" class="sidebar-item-text sidebar-link"> <span class="menu-text"><span class="chapter-number">18</span> <span class="chapter-title">Missing values</span></span></a> </div> </li> <li class="sidebar-item"> <div class="sidebar-item-container"> <a href="./joins.html" class="sidebar-item-text sidebar-link"> <span class="menu-text"><span class="chapter-number">19</span> <span class="chapter-title">Joins</span></span></a> </div> </li> </ul> </li> <li class="sidebar-item sidebar-item-section"> <div class="sidebar-item-container"> <a href="./import.html" class="sidebar-item-text sidebar-link"> <span class="menu-text">Import</span></a> <a class="sidebar-item-toggle text-start" data-bs-toggle="collapse" data-bs-target="#quarto-sidebar-section-4" role="navigation" aria-expanded="true" aria-label="Toggle section"> <i class="bi bi-chevron-right ms-2"></i> </a> </div> <ul id="quarto-sidebar-section-4" class="collapse list-unstyled sidebar-section depth1 show"> <li class="sidebar-item"> <div class="sidebar-item-container"> <a href="./spreadsheets.html" class="sidebar-item-text sidebar-link"> <span class="menu-text"><span class="chapter-number">20</span> <span class="chapter-title">Spreadsheets</span></span></a> </div> </li> <li class="sidebar-item"> <div class="sidebar-item-container"> <a href="./databases.html" class="sidebar-item-text sidebar-link"> <span class="menu-text"><span class="chapter-number">21</span> <span class="chapter-title">Databases</span></span></a> </div> </li> <li class="sidebar-item"> <div class="sidebar-item-container"> <a href="./arrow.html" class="sidebar-item-text sidebar-link"> <span class="menu-text"><span class="chapter-number">22</span> <span class="chapter-title">Arrow</span></span></a> </div> </li> <li class="sidebar-item"> <div class="sidebar-item-container"> <a href="./rectangling.html" class="sidebar-item-text sidebar-link"> <span class="menu-text"><span class="chapter-number">23</span> <span class="chapter-title">Hierarchical data</span></span></a> </div> </li> <li class="sidebar-item"> <div class="sidebar-item-container"> <a href="./webscraping.html" class="sidebar-item-text sidebar-link"> <span class="menu-text"><span class="chapter-number">24</span> <span class="chapter-title">Web scraping</span></span></a> </div> </li> </ul> </li> <li class="sidebar-item sidebar-item-section"> <div class="sidebar-item-container"> <a href="./program.html" class="sidebar-item-text sidebar-link"> <span class="menu-text">Program</span></a> <a class="sidebar-item-toggle text-start" data-bs-toggle="collapse" data-bs-target="#quarto-sidebar-section-5" role="navigation" aria-expanded="true" aria-label="Toggle section"> <i class="bi bi-chevron-right ms-2"></i> </a> </div> <ul id="quarto-sidebar-section-5" class="collapse list-unstyled sidebar-section depth1 show"> <li class="sidebar-item"> <div class="sidebar-item-container"> <a href="./functions.html" class="sidebar-item-text sidebar-link"> <span class="menu-text"><span class="chapter-number">25</span> <span class="chapter-title">Functions</span></span></a> </div> </li> <li class="sidebar-item"> <div class="sidebar-item-container"> <a href="./iteration.html" class="sidebar-item-text sidebar-link"> <span class="menu-text"><span class="chapter-number">26</span> <span class="chapter-title">Iteration</span></span></a> </div> </li> <li class="sidebar-item"> <div class="sidebar-item-container"> <a href="./base-R.html" class="sidebar-item-text sidebar-link"> <span class="menu-text"><span class="chapter-number">27</span> <span class="chapter-title">A field guide to base R</span></span></a> </div> </li> </ul> </li> <li class="sidebar-item sidebar-item-section"> <div class="sidebar-item-container"> <a href="./communicate.html" class="sidebar-item-text sidebar-link"> <span class="menu-text">Communicate</span></a> <a class="sidebar-item-toggle text-start" data-bs-toggle="collapse" data-bs-target="#quarto-sidebar-section-6" role="navigation" aria-expanded="true" aria-label="Toggle section"> <i class="bi bi-chevron-right ms-2"></i> </a> </div> <ul id="quarto-sidebar-section-6" class="collapse list-unstyled sidebar-section depth1 show"> <li class="sidebar-item"> <div class="sidebar-item-container"> <a href="./quarto.html" class="sidebar-item-text sidebar-link"> <span class="menu-text"><span class="chapter-number">28</span> <span class="chapter-title">Quarto</span></span></a> </div> </li> <li class="sidebar-item"> <div class="sidebar-item-container"> <a href="./quarto-formats.html" class="sidebar-item-text sidebar-link"> <span class="menu-text"><span class="chapter-number">29</span> <span class="chapter-title">Quarto formats</span></span></a> </div> </li> </ul> </li> </ul> </div> </nav><div id="quarto-sidebar-glass" class="quarto-sidebar-collapse-item" data-bs-toggle="collapse" data-bs-target=".quarto-sidebar-collapse-item"></div> <!-- margin-sidebar --> <div id="quarto-margin-sidebar" class="sidebar margin-sidebar"> <nav id="TOC" role="doc-toc" class="toc-active"><h2 id="toc-title">Table of contents</h2> <ul> <li><a href="#coding-basics" id="toc-coding-basics" class="nav-link active" data-scroll-target="#coding-basics"><span class="header-section-number">2.1</span> Coding basics</a></li> <li><a href="#comments" id="toc-comments" class="nav-link" data-scroll-target="#comments"><span class="header-section-number">2.2</span> Comments</a></li> <li><a href="#sec-whats-in-a-name" id="toc-sec-whats-in-a-name" class="nav-link" data-scroll-target="#sec-whats-in-a-name"><span class="header-section-number">2.3</span> What’s in a name?</a></li> <li><a href="#calling-functions" id="toc-calling-functions" class="nav-link" data-scroll-target="#calling-functions"><span class="header-section-number">2.4</span> Calling functions</a></li> <li><a href="#exercises" id="toc-exercises" class="nav-link" data-scroll-target="#exercises"><span class="header-section-number">2.5</span> Exercises</a></li> <li><a href="#summary" id="toc-summary" class="nav-link" data-scroll-target="#summary"><span class="header-section-number">2.6</span> Summary</a></li> </ul><div class="toc-actions"><ul><li><a href="https://github.com/hadley/r4ds/edit/main/workflow-basics.qmd" class="toc-action"><i class="bi bi-github"></i>Edit this page</a></li><li><a href="https://github.com/hadley/r4ds/issues/new" class="toc-action"><i class="bi empty"></i>Report an issue</a></li></ul></div></nav> </div> <!-- main --> <main class="content" id="quarto-document-content"><header id="title-block-header" class="quarto-title-block default"><nav class="quarto-page-breadcrumbs quarto-title-breadcrumbs d-none d-lg-block" aria-label="breadcrumb"><ol class="breadcrumb"><li class="breadcrumb-item"><a href="./whole-game.html">Whole game</a></li><li class="breadcrumb-item"><a href="./workflow-basics.html"><span class="chapter-number">2</span> <span class="chapter-title">Workflow: basics</span></a></li></ol></nav><div class="quarto-title"> <h1 class="title"><span id="sec-workflow-basics" class="quarto-section-identifier"><span class="chapter-number">2</span> <span class="chapter-title">Workflow: basics</span></span></h1> </div> <div class="quarto-title-meta"> </div> </header><p>You now have some experience running R code. We didn’t give you many details, but you’ve obviously figured out the basics, or you would’ve thrown this book away in frustration! Frustration is natural when you start programming in R because it is such a stickler for punctuation, and even one character out of place can cause it to complain. But while you should expect to be a little frustrated, take comfort in that this experience is typical and temporary: it happens to everyone, and the only way to get over it is to keep trying.</p> <p>Before we go any further, let’s ensure you’ve got a solid foundation in running R code and that you know some of the most helpful RStudio features.</p> <section id="coding-basics" class="level2" data-number="2.1"><h2 data-number="2.1" class="anchored" data-anchor-id="coding-basics"> <span class="header-section-number">2.1</span> Coding basics</h2> <p>Let’s review some basics we’ve omitted so far in the interest of getting you plotting as quickly as possible. You can use R to do basic math calculations:</p> <div class="cell"> <div class="sourceCode" id="cb1"><pre class="downlit sourceCode r code-with-copy"><code class="sourceCode R"><span><span class="fl">1</span> <span class="op">/</span> <span class="fl">200</span> <span class="op">*</span> <span class="fl">30</span></span> <span><span class="co">#> [1] 0.15</span></span> <span><span class="op">(</span><span class="fl">59</span> <span class="op">+</span> <span class="fl">73</span> <span class="op">+</span> <span class="fl">2</span><span class="op">)</span> <span class="op">/</span> <span class="fl">3</span></span> <span><span class="co">#> [1] 44.66667</span></span> <span><span class="fu"><a href="https://rdrr.io/r/base/Trig.html">sin</a></span><span class="op">(</span><span class="va">pi</span> <span class="op">/</span> <span class="fl">2</span><span class="op">)</span></span> <span><span class="co">#> [1] 1</span></span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div> </div> <p>You can create new objects with the assignment operator <code><-</code>:</p> <div class="cell"> <div class="sourceCode" id="cb2"><pre class="downlit sourceCode r code-with-copy"><code class="sourceCode R"><span><span class="va">x</span> <span class="op"><-</span> <span class="fl">3</span> <span class="op">*</span> <span class="fl">4</span></span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div> </div> <p>Note that the value of <code>x</code> is not printed, it’s just stored. If you want to view the value, type <code>x</code> in the console.</p> <p>You can <strong>c</strong>ombine multiple elements into a vector with <code><a href="https://rdrr.io/r/base/c.html">c()</a></code>:</p> <div class="cell"> <div class="sourceCode" id="cb3"><pre class="downlit sourceCode r code-with-copy"><code class="sourceCode R"><span><span class="va">primes</span> <span class="op"><-</span> <span class="fu"><a href="https://rdrr.io/r/base/c.html">c</a></span><span class="op">(</span><span class="fl">2</span>, <span class="fl">3</span>, <span class="fl">5</span>, <span class="fl">7</span>, <span class="fl">11</span>, <span class="fl">13</span><span class="op">)</span></span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div> </div> <p>And basic arithmetic on vectors is applied to every element of of the vector:</p> <div class="cell"> <div class="sourceCode" id="cb4"><pre class="downlit sourceCode r code-with-copy"><code class="sourceCode R"><span><span class="va">primes</span> <span class="op">*</span> <span class="fl">2</span></span> <span><span class="co">#> [1] 4 6 10 14 22 26</span></span> <span><span class="va">primes</span> <span class="op">-</span> <span class="fl">1</span></span> <span><span class="co">#> [1] 1 2 4 6 10 12</span></span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div> </div> <p>All R statements where you create objects, <strong>assignment</strong> statements, have the same form:</p> <div class="cell"> <div class="sourceCode" id="cb5"><pre class="downlit sourceCode r code-with-copy"><code class="sourceCode R"><span><span class="va">object_name</span> <span class="op"><-</span> <span class="va">value</span></span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div> </div> <p>When reading that code, say “object name gets value” in your head.</p> <p>You will make lots of assignments, and <code><-</code> is a pain to type. You can save time with RStudio’s keyboard shortcut: Alt + - (the minus sign). Notice that RStudio automatically surrounds <code><-</code> with spaces, which is a good code formatting practice. Code can be miserable to read on a good day, so giveyoureyesabreak and use spaces.</p> </section><section id="comments" class="level2" data-number="2.2"><h2 data-number="2.2" class="anchored" data-anchor-id="comments"> <span class="header-section-number">2.2</span> Comments</h2> <p>R will ignore any text after <code>#</code> for that line. This allows you to write <strong>comments</strong>, text that is ignored by R but read by other humans. We’ll sometimes include comments in examples explaining what’s happening with the code.</p> <p>Comments can be helpful for briefly describing what the following code does.</p> <div class="cell"> <div class="sourceCode" id="cb6"><pre class="downlit sourceCode r code-with-copy"><code class="sourceCode R"><span><span class="co"># create vector of primes</span></span> <span><span class="va">primes</span> <span class="op"><-</span> <span class="fu"><a href="https://rdrr.io/r/base/c.html">c</a></span><span class="op">(</span><span class="fl">2</span>, <span class="fl">3</span>, <span class="fl">5</span>, <span class="fl">7</span>, <span class="fl">11</span>, <span class="fl">13</span><span class="op">)</span></span> <span></span> <span><span class="co"># multiply primes by 2</span></span> <span><span class="va">primes</span> <span class="op">*</span> <span class="fl">2</span></span> <span><span class="co">#> [1] 4 6 10 14 22 26</span></span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div> </div> <p>With short pieces of code like this, leaving a comment for every single line of code might not be necessary. But as the code you’re writing gets more complex, comments can save you (and your collaborators) a lot of time figuring out what was done in the code.</p> <p>Use comments to explain the <em>why</em> of your code, not the <em>how</em> or the <em>what</em>. The <em>what</em> and <em>how</em> of your code are always possible to figure out, even if it might be tedious, by carefully reading it. If you describe every step in the comments, and then change the code, you will have to remember to update the comments as well or it will be confusing when you return to your code in the future.</p> <p>Figuring out <em>why</em> something was done is much more difficult, if not impossible. For example, <code>geom_smooth()</code> has an argument called <code>span</code>, which controls the smoothness of the curve, with larger values yielding a smoother curve. Suppose you decide to change the value of <code>span</code> from its default of 0.75 to 0.9: it’s easy for a future reader to understand <em>what</em> is happening, but unless you note your thinking in a comment, no one will understand <em>why</em> you changed the default.</p> <p>For data analysis code, use comments to explain your overall plan of attack and record important insights as you encounter them. There’s no way to re-capture this knowledge from the code itself.</p> </section><section id="sec-whats-in-a-name" class="level2" data-number="2.3"><h2 data-number="2.3" class="anchored" data-anchor-id="sec-whats-in-a-name"> <span class="header-section-number">2.3</span> What’s in a name?</h2> <p>Object names must start with a letter and can only contain letters, numbers, <code>_</code>, and <code>.</code>. You want your object names to be descriptive, so you’ll need to adopt a convention for multiple words. We recommend <strong>snake_case</strong>, where you separate lowercase words with <code>_</code>.</p> <div class="cell"> <div class="sourceCode" id="cb7"><pre class="downlit sourceCode r code-with-copy"><code class="sourceCode R"><span><span class="va">i_use_snake_case</span></span> <span><span class="va">otherPeopleUseCamelCase</span></span> <span><span class="va">some.people.use.periods</span></span> <span><span class="va">And_aFew.People_RENOUNCEconvention</span></span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div> </div> <p>We’ll return to names again when we discuss code style in <a href="workflow-style.html" class="quarto-xref"><span>Chapter 4</span></a>.</p> <p>You can inspect an object by typing its name:</p> <div class="cell"> <div class="sourceCode" id="cb8"><pre class="downlit sourceCode r code-with-copy"><code class="sourceCode R"><span><span class="va">x</span></span> <span><span class="co">#> [1] 12</span></span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div> </div> <p>Make another assignment:</p> <div class="cell"> <div class="sourceCode" id="cb9"><pre class="downlit sourceCode r code-with-copy"><code class="sourceCode R"><span><span class="va">this_is_a_really_long_name</span> <span class="op"><-</span> <span class="fl">2.5</span></span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div> </div> <p>To inspect this object, try out RStudio’s completion facility: type “this”, press TAB, add characters until you have a unique prefix, then press return.</p> <p>Let’s assume you made a mistake, and that the value of <code>this_is_a_really_long_name</code> should be 3.5, not 2.5. You can use another keyboard shortcut to help you fix it. For example, you can press ↑ to bring the last command you typed and edit it. Or, type “this” then press Cmd/Ctrl + ↑ to list all the commands you’ve typed that start with those letters. Use the arrow keys to navigate, then press enter to retype the command. Change 2.5 to 3.5 and rerun.</p> <p>Make yet another assignment:</p> <div class="cell"> <div class="sourceCode" id="cb10"><pre class="downlit sourceCode r code-with-copy"><code class="sourceCode R"><span><span class="va">r_rocks</span> <span class="op"><-</span> <span class="fl">2</span><span class="op">^</span><span class="fl">3</span></span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div> </div> <p>Let’s try to inspect it:</p> <div class="cell"> <div class="sourceCode" id="cb11"><pre class="downlit sourceCode r code-with-copy"><code class="sourceCode R"><span><span class="va">r_rock</span></span> <span><span class="co">#> Error: object 'r_rock' not found</span></span> <span><span class="va">R_rocks</span></span> <span><span class="co">#> Error: object 'R_rocks' not found</span></span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div> </div> <p>This illustrates the implied contract between you and R: R will do the tedious computations for you, but in exchange, you must be completely precise in your instructions. If not, you’re likely to get an error that says the object you’re looking for was not found. Typos matter; R can’t read your mind and say, “oh, they probably meant <code>r_rocks</code> when they typed <code>r_rock</code>”. Case matters; similarly, R can’t read your mind and say, “oh, they probably meant <code>r_rocks</code> when they typed <code>R_rocks</code>”.</p> </section><section id="calling-functions" class="level2" data-number="2.4"><h2 data-number="2.4" class="anchored" data-anchor-id="calling-functions"> <span class="header-section-number">2.4</span> Calling functions</h2> <p>R has a large collection of built-in functions that are called like this:</p> <div class="cell"> <div class="sourceCode" id="cb12"><pre class="downlit sourceCode r code-with-copy"><code class="sourceCode R"><span><span class="fu">function_name</span><span class="op">(</span>argument1 <span class="op">=</span> <span class="va">value1</span>, argument2 <span class="op">=</span> <span class="va">value2</span>, <span class="va">...</span><span class="op">)</span></span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div> </div> <p>Let’s try using <code><a href="https://rdrr.io/r/base/seq.html">seq()</a></code>, which makes regular <strong>seq</strong>uences of numbers, and while we’re at it, learn more helpful features of RStudio. Type <code>se</code> and hit TAB. A popup shows you possible completions. Specify <code><a href="https://rdrr.io/r/base/seq.html">seq()</a></code> by typing more (a <code>q</code>) to disambiguate or by using ↑/↓ arrows to select. Notice the floating tooltip that pops up, reminding you of the function’s arguments and purpose. If you want more help, press F1 to get all the details in the help tab in the lower right pane.</p> <p>When you’ve selected the function you want, press TAB again. RStudio will add matching opening (<code>(</code>) and closing (<code>)</code>) parentheses for you. Type the name of the first argument, <code>from</code>, and set it equal to <code>1</code>. Then, type the name of the second argument, <code>to</code>, and set it equal to <code>10</code>. Finally, hit return.</p> <div class="cell"> <div class="sourceCode" id="cb13"><pre class="downlit sourceCode r code-with-copy"><code class="sourceCode R"><span><span class="fu"><a href="https://rdrr.io/r/base/seq.html">seq</a></span><span class="op">(</span>from <span class="op">=</span> <span class="fl">1</span>, to <span class="op">=</span> <span class="fl">10</span><span class="op">)</span></span> <span><span class="co">#> [1] 1 2 3 4 5 6 7 8 9 10</span></span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div> </div> <p>We often omit the names of the first several arguments in function calls, so we can rewrite this as follows:</p> <div class="cell"> <div class="sourceCode" id="cb14"><pre class="downlit sourceCode r code-with-copy"><code class="sourceCode R"><span><span class="fu"><a href="https://rdrr.io/r/base/seq.html">seq</a></span><span class="op">(</span><span class="fl">1</span>, <span class="fl">10</span><span class="op">)</span></span> <span><span class="co">#> [1] 1 2 3 4 5 6 7 8 9 10</span></span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div> </div> <p>Type the following code and notice that RStudio provides similar assistance with the paired quotation marks:</p> <div class="cell"> <div class="sourceCode" id="cb15"><pre class="downlit sourceCode r code-with-copy"><code class="sourceCode R"><span><span class="va">x</span> <span class="op"><-</span> <span class="st">"hello world"</span></span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div> </div> <p>Quotation marks and parentheses must always come in a pair. RStudio does its best to help you, but it’s still possible to mess up and end up with a mismatch. If this happens, R will show you the continuation character “+”:</p> <pre><code>> x <- "hello +</code></pre> <p>The <code>+</code> tells you that R is waiting for more input; it doesn’t think you’re done yet. Usually, this means you’ve forgotten either a <code>"</code> or a <code>)</code>. Either add the missing pair, or press ESCAPE to abort the expression and try again.</p> <p>Note that the environment tab in the upper right pane displays all of the objects that you’ve created:</p> <div class="cell"> <div class="cell-output-display"> <div> <figure class="figure"><p><img src="screenshots/rstudio-env.png" class="img-fluid figure-img" alt="Environment tab of RStudio which shows r_rocks, this_is_a_really_long_name, x, and y in the Global Environment." width="778"></p> </figure> </div> </div> </div> </section><section id="exercises" class="level2" data-number="2.5"><h2 data-number="2.5" class="anchored" data-anchor-id="exercises"> <span class="header-section-number">2.5</span> Exercises</h2> <ol type="1"> <li> <p>Why does this code not work?</p> <div class="cell"> <div class="sourceCode" id="cb17"><pre class="downlit sourceCode r code-with-copy"><code class="sourceCode R"><span><span class="va">my_variable</span> <span class="op"><-</span> <span class="fl">10</span></span> <span><span class="va">my_varıable</span></span> <span><span class="co">#> Error: object 'my_varıable' not found</span></span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div> </div> <p>Look carefully! (This may seem like an exercise in pointlessness, but training your brain to notice even the tiniest difference will pay off when programming.)</p> </li> <li> <p>Tweak each of the following R commands so that they run correctly:</p> <div class="cell"> <div class="sourceCode cell-code" id="cb18"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb18-1"><a href="#cb18-1" aria-hidden="true" tabindex="-1"></a><span class="fu">libary</span>(todyverse)</span> <span id="cb18-2"><a href="#cb18-2" aria-hidden="true" tabindex="-1"></a></span> <span id="cb18-3"><a href="#cb18-3" aria-hidden="true" tabindex="-1"></a><span class="fu">ggplot</span>(<span class="at">dTA =</span> mpg) <span class="sc">+</span> </span> <span id="cb18-4"><a href="#cb18-4" aria-hidden="true" tabindex="-1"></a> <span class="fu">geom_point</span>(<span class="at">maping =</span> <span class="fu">aes</span>(<span class="at">x =</span> displ <span class="at">y =</span> hwy)) <span class="sc">+</span></span> <span id="cb18-5"><a href="#cb18-5" aria-hidden="true" tabindex="-1"></a> <span class="fu">geom_smooth</span>(<span class="at">method =</span> <span class="st">"lm)</span></span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div> </div> </li> <li><p>Press Option + Shift + K / Alt + Shift + K. What happens? How can you get to the same place using the menus?</p></li> <li> <p>Let’s revisit an exercise from the <a href="data-visualize.html#sec-ggsave" class="quarto-xref"><span>Section 1.6</span></a>. Run the following lines of code. Which of the two plots is saved as <code>mpg-plot.png</code>? Why?</p> <div class="cell"> <div class="sourceCode" id="cb19"><pre class="downlit sourceCode r code-with-copy"><code class="sourceCode R"><span><span class="va">my_bar_plot</span> <span class="op"><-</span> <span class="fu">ggplot</span><span class="op">(</span><span class="va">mpg</span>, <span class="fu">aes</span><span class="op">(</span>x <span class="op">=</span> <span class="va">class</span><span class="op">)</span><span class="op">)</span> <span class="op">+</span></span> <span> <span class="fu">geom_bar</span><span class="op">(</span><span class="op">)</span></span> <span><span class="va">my_scatter_plot</span> <span class="op"><-</span> <span class="fu">ggplot</span><span class="op">(</span><span class="va">mpg</span>, <span class="fu">aes</span><span class="op">(</span>x <span class="op">=</span> <span class="va">cty</span>, y <span class="op">=</span> <span class="va">hwy</span><span class="op">)</span><span class="op">)</span> <span class="op">+</span></span> <span> <span class="fu">geom_point</span><span class="op">(</span><span class="op">)</span></span> <span><span class="fu">ggsave</span><span class="op">(</span>filename <span class="op">=</span> <span class="st">"mpg-plot.png"</span>, plot <span class="op">=</span> <span class="va">my_bar_plot</span><span class="op">)</span></span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div> </div> </li> </ol></section><section id="summary" class="level2" data-number="2.6"><h2 data-number="2.6" class="anchored" data-anchor-id="summary"> <span class="header-section-number">2.6</span> Summary</h2> <p>Now that you’ve learned a little more about how R code works, and some tips to help you understand your code when you come back to it in the future. In the next chapter, we’ll continue your data science journey by teaching you about dplyr, the tidyverse package that helps you transform data, whether it’s selecting important variables, filtering down to rows of interest, or computing summary statistics.</p> </section></main><!-- /main --><script id="quarto-html-after-body" type="application/javascript"> window.document.addEventListener("DOMContentLoaded", function (event) { const toggleBodyColorMode = (bsSheetEl) => { const mode = bsSheetEl.getAttribute("data-mode"); const bodyEl = window.document.querySelector("body"); if (mode === "dark") { bodyEl.classList.add("quarto-dark"); bodyEl.classList.remove("quarto-light"); } else { bodyEl.classList.add("quarto-light"); bodyEl.classList.remove("quarto-dark"); } } const toggleBodyColorPrimary = () => { const bsSheetEl = window.document.querySelector("link#quarto-bootstrap"); if (bsSheetEl) { toggleBodyColorMode(bsSheetEl); } } toggleBodyColorPrimary(); const icon = ""; const anchorJS = new window.AnchorJS(); anchorJS.options = { placement: 'right', icon: icon }; anchorJS.add('.anchored'); const isCodeAnnotation = (el) => { for (const clz of el.classList) { if (clz.startsWith('code-annotation-')) { return true; } } return false; } const onCopySuccess = function(e) { // button target const button = e.trigger; // don't keep focus button.blur(); // flash "checked" button.classList.add('code-copy-button-checked'); var currentTitle = button.getAttribute("title"); button.setAttribute("title", "Copied!"); let tooltip; if (window.bootstrap) { button.setAttribute("data-bs-toggle", "tooltip"); button.setAttribute("data-bs-placement", "left"); button.setAttribute("data-bs-title", "Copied!"); tooltip = new bootstrap.Tooltip(button, { trigger: "manual", customClass: "code-copy-button-tooltip", offset: [0, -8]}); tooltip.show(); } setTimeout(function() { if (tooltip) { tooltip.hide(); button.removeAttribute("data-bs-title"); button.removeAttribute("data-bs-toggle"); button.removeAttribute("data-bs-placement"); } button.setAttribute("title", currentTitle); button.classList.remove('code-copy-button-checked'); }, 1000); // clear code selection e.clearSelection(); } const getTextToCopy = function(trigger) { const codeEl = trigger.previousElementSibling.cloneNode(true); for (const childEl of codeEl.children) { if (isCodeAnnotation(childEl)) { childEl.remove(); } } return codeEl.innerText; } const clipboard = new window.ClipboardJS('.code-copy-button:not([data-in-quarto-modal])', { text: getTextToCopy }); clipboard.on('success', onCopySuccess); if (window.document.getElementById('quarto-embedded-source-code-modal')) { const clipboardModal = new window.ClipboardJS('.code-copy-button[data-in-quarto-modal]', { text: getTextToCopy, container: window.document.getElementById('quarto-embedded-source-code-modal') }); clipboardModal.on('success', onCopySuccess); } var localhostRegex = new RegExp(/^(?:http|https):\/\/localhost\:?[0-9]*\//); var mailtoRegex = new RegExp(/^mailto:/); var filterRegex = new RegExp("https:\/\/r4ds\.hadley\.nz\/"); var isInternal = (href) => { return filterRegex.test(href) || localhostRegex.test(href) || mailtoRegex.test(href); } // Inspect non-navigation links and adorn them if external var links = window.document.querySelectorAll('a[href]:not(.nav-link):not(.navbar-brand):not(.toc-action):not(.sidebar-link):not(.sidebar-item-toggle):not(.pagination-link):not(.no-external):not([aria-hidden]):not(.dropdown-item):not(.quarto-navigation-tool):not(.about-link)'); for (var i=0; i<links.length; i++) { const link = links[i]; if (!isInternal(link.href)) { // undo the damage that might have been done by quarto-nav.js in the case of // links that we want to consider external if (link.dataset.originalHref !== undefined) { link.href = link.dataset.originalHref; } } } function tippyHover(el, contentFn, onTriggerFn, onUntriggerFn) { const config = { allowHTML: true, maxWidth: 500, delay: 100, arrow: false, appendTo: function(el) { return el.parentElement; }, interactive: true, interactiveBorder: 10, theme: 'quarto', placement: 'bottom-start', }; if (contentFn) { config.content = contentFn; } if (onTriggerFn) { config.onTrigger = onTriggerFn; } if (onUntriggerFn) { config.onUntrigger = onUntriggerFn; } window.tippy(el, config); } const noterefs = window.document.querySelectorAll('a[role="doc-noteref"]'); for (var i=0; i<noterefs.length; i++) { const ref = noterefs[i]; tippyHover(ref, function() { // use id or data attribute instead here let href = ref.getAttribute('data-footnote-href') || ref.getAttribute('href'); try { href = new URL(href).hash; } catch {} const id = href.replace(/^#\/?/, ""); const note = window.document.getElementById(id); if (note) { return note.innerHTML; } else { return ""; } }); } const xrefs = window.document.querySelectorAll('a.quarto-xref'); const processXRef = (id, note) => { // Strip column container classes const stripColumnClz = (el) => { el.classList.remove("page-full", "page-columns"); if (el.children) { for (const child of el.children) { stripColumnClz(child); } } } stripColumnClz(note) if (id === null || id.startsWith('sec-')) { // Special case sections, only their first couple elements const container = document.createElement("div"); if (note.children && note.children.length > 2) { container.appendChild(note.children[0].cloneNode(true)); for (let i = 1; i < note.children.length; i++) { const child = note.children[i]; if (child.tagName === "P" && child.innerText === "") { continue; } else { container.appendChild(child.cloneNode(true)); break; } } if (window.Quarto?.typesetMath) { window.Quarto.typesetMath(container); } return container.innerHTML } else { if (window.Quarto?.typesetMath) { window.Quarto.typesetMath(note); } return note.innerHTML; } } else { // Remove any anchor links if they are present const anchorLink = note.querySelector('a.anchorjs-link'); if (anchorLink) { anchorLink.remove(); } if (window.Quarto?.typesetMath) { window.Quarto.typesetMath(note); } if (note.classList.contains("callout")) { return note.outerHTML; } else { return note.innerHTML; } } } for (var i=0; i<xrefs.length; i++) { const xref = xrefs[i]; tippyHover(xref, undefined, function(instance) { instance.disable(); let url = xref.getAttribute('href'); let hash = undefined; if (url.startsWith('#')) { hash = url; } else { try { hash = new URL(url).hash; } catch {} } if (hash) { const id = hash.replace(/^#\/?/, ""); const note = window.document.getElementById(id); if (note !== null) { try { const html = processXRef(id, note.cloneNode(true)); instance.setContent(html); } finally { instance.enable(); instance.show(); } } else { // See if we can fetch this fetch(url.split('#')[0]) .then(res => res.text()) .then(html => { const parser = new DOMParser(); const htmlDoc = parser.parseFromString(html, "text/html"); const note = htmlDoc.getElementById(id); if (note !== null) { const html = processXRef(id, note); instance.setContent(html); } }).finally(() => { instance.enable(); instance.show(); }); } } else { // See if we can fetch a full url (with no hash to target) // This is a special case and we should probably do some content thinning / targeting fetch(url) .then(res => res.text()) .then(html => { const parser = new DOMParser(); const htmlDoc = parser.parseFromString(html, "text/html"); const note = htmlDoc.querySelector('main.content'); if (note !== null) { // This should only happen for chapter cross references // (since there is no id in the URL) // remove the first header if (note.children.length > 0 && note.children[0].tagName === "HEADER") { note.children[0].remove(); } const html = processXRef(null, note); instance.setContent(html); } }).finally(() => { instance.enable(); instance.show(); }); } }, function(instance) { }); } let selectedAnnoteEl; const selectorForAnnotation = ( cell, annotation) => { let cellAttr = 'data-code-cell="' + cell + '"'; let lineAttr = 'data-code-annotation="' + annotation + '"'; const selector = 'span[' + cellAttr + '][' + lineAttr + ']'; return selector; } const selectCodeLines = (annoteEl) => { const doc = window.document; const targetCell = annoteEl.getAttribute("data-target-cell"); const targetAnnotation = annoteEl.getAttribute("data-target-annotation"); const annoteSpan = window.document.querySelector(selectorForAnnotation(targetCell, targetAnnotation)); const lines = annoteSpan.getAttribute("data-code-lines").split(","); const lineIds = lines.map((line) => { return targetCell + "-" + line; }) let top = null; let height = null; let parent = null; if (lineIds.length > 0) { //compute the position of the single el (top and bottom and make a div) const el = window.document.getElementById(lineIds[0]); top = el.offsetTop; height = el.offsetHeight; parent = el.parentElement.parentElement; if (lineIds.length > 1) { const lastEl = window.document.getElementById(lineIds[lineIds.length - 1]); const bottom = lastEl.offsetTop + lastEl.offsetHeight; height = bottom - top; } if (top !== null && height !== null && parent !== null) { // cook up a div (if necessary) and position it let div = window.document.getElementById("code-annotation-line-highlight"); if (div === null) { div = window.document.createElement("div"); div.setAttribute("id", "code-annotation-line-highlight"); div.style.position = 'absolute'; parent.appendChild(div); } div.style.top = top - 2 + "px"; div.style.height = height + 4 + "px"; div.style.left = 0; let gutterDiv = window.document.getElementById("code-annotation-line-highlight-gutter"); if (gutterDiv === null) { gutterDiv = window.document.createElement("div"); gutterDiv.setAttribute("id", "code-annotation-line-highlight-gutter"); gutterDiv.style.position = 'absolute'; const codeCell = window.document.getElementById(targetCell); const gutter = codeCell.querySelector('.code-annotation-gutter'); gutter.appendChild(gutterDiv); } gutterDiv.style.top = top - 2 + "px"; gutterDiv.style.height = height + 4 + "px"; } selectedAnnoteEl = annoteEl; } }; const unselectCodeLines = () => { const elementsIds = ["code-annotation-line-highlight", "code-annotation-line-highlight-gutter"]; elementsIds.forEach((elId) => { const div = window.document.getElementById(elId); if (div) { div.remove(); } }); selectedAnnoteEl = undefined; }; // Handle positioning of the toggle window.addEventListener( "resize", throttle(() => { elRect = undefined; if (selectedAnnoteEl) { selectCodeLines(selectedAnnoteEl); } }, 10) ); function throttle(fn, ms) { let throttle = false; let timer; return (...args) => { if(!throttle) { // first call gets through fn.apply(this, args); throttle = true; } else { // all the others get throttled if(timer) clearTimeout(timer); // cancel #2 timer = setTimeout(() => { fn.apply(this, args); timer = throttle = false; }, ms); } }; } // Attach click handler to the DT const annoteDls = window.document.querySelectorAll('dt[data-target-cell]'); for (const annoteDlNode of annoteDls) { annoteDlNode.addEventListener('click', (event) => { const clickedEl = event.target; if (clickedEl !== selectedAnnoteEl) { unselectCodeLines(); const activeEl = window.document.querySelector('dt[data-target-cell].code-annotation-active'); if (activeEl) { activeEl.classList.remove('code-annotation-active'); } selectCodeLines(clickedEl); clickedEl.classList.add('code-annotation-active'); } else { // Unselect the line unselectCodeLines(); clickedEl.classList.remove('code-annotation-active'); } }); } const findCites = (el) => { const parentEl = el.parentElement; if (parentEl) { const cites = parentEl.dataset.cites; if (cites) { return { el, cites: cites.split(' ') }; } else { return findCites(el.parentElement) } } else { return undefined; } }; var bibliorefs = window.document.querySelectorAll('a[role="doc-biblioref"]'); for (var i=0; i<bibliorefs.length; i++) { const ref = bibliorefs[i]; const citeInfo = findCites(ref); if (citeInfo) { tippyHover(citeInfo.el, function() { var popup = window.document.createElement('div'); citeInfo.cites.forEach(function(cite) { var citeDiv = window.document.createElement('div'); citeDiv.classList.add('hanging-indent'); citeDiv.classList.add('csl-entry'); var biblioDiv = window.document.getElementById('ref-' + cite); if (biblioDiv) { citeDiv.innerHTML = biblioDiv.innerHTML; } popup.appendChild(citeDiv); }); return popup.innerHTML; }); } } }); </script><nav class="page-navigation"><div class="nav-page nav-page-previous"> <a href="./data-visualize.html" class="pagination-link" aria-label="Data visualization"> <i class="bi bi-arrow-left-short"></i> <span class="nav-page-text"><span class="chapter-number">1</span> <span class="chapter-title">Data visualization</span></span> </a> </div> <div class="nav-page nav-page-next"> <a href="./data-transform.html" class="pagination-link" aria-label="Data transformation"> <span class="nav-page-text"><span class="chapter-number">3</span> <span class="chapter-title">Data transformation</span></span> <i class="bi bi-arrow-right-short"></i> </a> </div> </nav> </div> <!-- /content --> <footer class="footer"><div class="nav-footer"> <div class="nav-footer-left"> <p>R for Data Science (2e) was written by Hadley Wickham, Mine Çetinkaya-Rundel, and Garrett Grolemund.</p> </div> <div class="nav-footer-center"> <div class="toc-actions d-sm-block d-md-none"><ul><li><a href="https://github.com/hadley/r4ds/edit/main/workflow-basics.qmd" class="toc-action"><i class="bi bi-github"></i>Edit this page</a></li><li><a href="https://github.com/hadley/r4ds/issues/new" class="toc-action"><i class="bi empty"></i>Report an issue</a></li></ul></div></div> <div class="nav-footer-right"> <p>This book was built with <a href="https://quarto.org/">Quarto</a>.</p> </div> </div> </footer> </body></html>