01-1: Introduction to R

Tips to make the most of the lecture notes

Transcript

Two navigation tricks before we start on R itself, and they are worth a moment because this is the deck you will come back to most. The three stacked horizontal lines in the bottom-left corner open a table of contents, so you can jump straight to a section instead of arrowing through everything in between. Pressing the letter o gives you an overview of every slide at once, which is the fastest way to find something you only half remember. This lecture holds the basic vocabulary of the whole course, what a vector is, what a data frame is, how to install a package, so being able to find one specific slide quickly matters more here than anywhere else.

  • Click the three stacked horizontal lines in the bottom-left corner of the slide to open the table of contents, then jump to whichever section you want

  • Press the “o” key to see an overview of every slide at once

Transcript

These notes are interactive, and since this is the first lecture it is worth explaining properly. The box with the pale blue background is a live code area: R is running inside your browser, so you can type in it and run it here, before you have R installed on your own machine at all. Hit Run Code to run everything in the box, or highlight part of it and press Command and Enter on a Mac, or Control and Enter on Windows, to run just that part. The icon of two stacked sheets of paper in the top-right corner copies the code so you can paste it into RStudio later. The reload button next to it puts the original code back when you have edited yourself into a mess, which you should feel free to do. One more, at the right end of the toolbar: the eye icon hides that cell’s output and a second click brings it back. Some of these results run long, and once you have read one it is just pushing the rest of the slide out of view. Do experiment in these boxes. Changing a number and running it again is the fastest way to find out what something does, and nothing you type here can break anything.

  • The box with the pale blue background is where you write code. We refer to it below as the “code area”.
  • Hit the “Run Code” button to execute all the code inside the code area.
  • To run only part of the code, highlight the part you want and press Command + Enter on a Mac, or Ctrl + Enter on Windows.
  • To run the code on your own computer, click the icon of two stacked sheets of paper in the top-right corner of the chunk. That copies the contents of the code area, which you can then paste into R.
  • Click the reload button, just to the left of the copy button, to revert to the original code.
  • Click the eye icon to hide a code area’s output, and click it again to bring it back. It sits at the right end of the toolbar, next to the copy button, or on the Output banner when the output is shown beside the code. Useful when a long result pushes the rest of the slide out of view.

Learning Objectives

Transcript

Let’s start with where this course is going, so the individual pieces have somewhere to sit. There are two broad aims. The first is simply to get you comfortable with programming as an activity, which for many of you is new and which turns out to be less hard than it first feels. The second, and the real goal, is that by the end you can use R to carry out research on your own: manipulate data, visualize it, report your results, and handle spatial data. Those four sub-goals map onto the chapters ahead, so when you find yourself wondering why we are spending a week on something, it is serving one of them.

  • Become familiar with programming
  • Become capable of using R to conduct research independently
    • Manipulate data
    • Visualize data
    • Report results
    • Manage spatial data

Table of contents

Transcript

Here is the shape of today in particular. Four parts. We start with R and RStudio themselves, what they are and how to get them installed and get oriented. Then object types, which is the conceptual core of the day and the part that makes the rest of the language make sense. Then functions and packages, which is how you actually get anything done. And we finish by going back over the four object types in more depth. If you get lost at any point, these headings are clickable, so you can jump back to wherever things stopped making sense.

  1. Introduction to R and RStudio
  2. Various object types
  3. Functions and packages
  4. A bit more on vector, matrix, list, and data.frame

Introduction to R and RStudio


R

Transcript

So what is R? It is a statistical programming language, genuinely popular in both academia and industry, and that second part matters for you because it means the skill travels outside the university. It began as software for doing statistics, designed by statisticians, and that origin still shows in how it thinks about data. It is open source and free, which is not a small thing. And it has grown enormously through its users: state-of-the-art statistical methods often arrive as R packages written by the very people who invented the method, and it has spread well beyond statistics into mapping and large-scale data work.

  • A very popular statistical programming language, used in both academia and industry

  • Started out as software for doing statistics, designed by a group of statisticians

  • Open-source and free

  • Has evolved rapidly through the contributions of its users, and continues to:

    • State-of-the-art statistical methods (machine learning algorithms, for example) written by the people who developed the methods
    • Geographic information systems (GIS)
    • Handling and analysis of large datasets

RStudio

Transcript

Here is something worth being blunt about: R’s own interface is poor. If you install R and open it directly you get a fairly bare window, and it does not make a good first impression. RStudio is a separate program that sits on top of R and gives you a proper working environment, and it is by far the most popular way people actually use the language. So you will install two things, and you will then spend essentially all of your time in the second one. The screenshot shows that bare R console, not RStudio. It is on screen so you can recognize the interface we are choosing not to use and understand why we add RStudio on top of R.

  • R’s own graphical user interface is very poor
  • RStudio is by far the most popular graphical user interface for R

R User Interface

Install R and RStudio

Transcript

Two installations, and the order matters: R first, then RStudio. The reason is that RStudio goes looking for an existing R installation when it starts up, so doing it the other way round can leave you with a program that cannot find its engine. Both links are on the slide, both are free, and both are ordinary installers for your operating system. If you have not done this yet, please do it now rather than later, because everything from this point on assumes you can open RStudio and see a console.

Introduction to RStudio

Transcript

Let’s get oriented in the window, because I will be referring to these panes constantly. There are four. Upper left is your R script, where you write code you intend to keep. Lower left is the console, where code actually runs and where you try things out. Upper right is the environment, which lists the objects you have created, and you will find yourself glancing at it often. Lower right holds files, plots, packages, and help. Two small things worth doing early: set the appearance to something you find comfortable to look at, and rearrange the pane layout if the default does not suit how you work.

Four panes

  • R script (upper left)
  • Console (lower left)
  • Environment (upper right)
  • Files, plots, packages, and help (lower right)

Small tips

  • Appearance
  • Pane Layout

Getting started with R and RStudio


Objectives

Transcript

This section is where you start actually typing, so four things to come away with. You will do some basic arithmetic, which is a low-risk way of confirming that everything is installed and working. You will learn to define objects, which is the single most important habit in the language. You will meet the different object types, which is the conceptual part of the day. And you will get used to driving RStudio while you do it, because the tool and the language really are learned together rather than one after the other.

Learn how to

  • do basic mathematical operations
  • define objects in R
  • learn different object types
  • use RStudio at the same time

Basic element types (atomic mode)

Transcript

Before we get to objects, the raw materials they are made of. There are five basic types. Integer literals require an L suffix. Numeric, also called double, is R’s default numeric type and can represent whole or fractional values, and this is the one you will meet most often. Complex has an imaginary part and you will almost certainly never need it in this course. Logical is just TRUE or FALSE, and it becomes enormously important once you start filtering data. And character is text, written inside quotation marks. Note the remark on that last one: you cannot do arithmetic on characters. That sounds obvious right now and it will still catch you out later.

  • integer: integer literals require an L suffix, e.g. 1L, 3L
  • numeric (double): R’s default numeric type; can represent whole or fractional values, e.g. 1, 1.3
  • complex: numbers with an imaginary part, e.g. 1+2i (rarely needed in this course)
  • logical (boolean): TRUE or FALSE
  • character: text, e.g. "Nebraska" (arithmetic is not allowed)

Basic arithmetic: R as a calculator

Transcript

Let’s start by using R as nothing more than a calculator, because it is a comfortable way in. Addition, subtraction, multiplication with the asterisk, exponentiation with the caret, division with the slash. Then two you may not have met: double percent gives the remainder after division, and percent-slash gives the whole-number quotient. Those two come in useful more often than you would guess. Try the code in the box. And take note of the tip, because you will use it thousands of times: you run selected code with command and enter on a Mac, control and enter on Windows.


RStudio Tip

You can run the selected codes by hitting

  • Mac: command + enter
  • Windows: Control + enter

Comments

Transcript

Anything after a hash on a line is ignored by R, and that is how you write comments. Use them, and use them more than you think you need to, because the person most likely to read your code and wonder what on earth you were thinking is you, three months from now. A comment can take up a whole line or sit at the end of a line of code. The callout explains a style you will see throughout these notes: a hash, some dashes, the text, some dashes, a hash. The dashes mean nothing at all to R; they simply make section headings easy to pick out when you are scrolling through a long script.

Anything after a # on a line is ignored by R. Use comments to explain what your code is doing, to yourself and to anyone else who reads it.

The style used in these notes

You will see #--- like this ---# throughout the course. The dashes carry no special meaning; they simply make section headings easy to pick out in a long script.

Logical values and operators

Transcript

Now comparisons, which produce logical values. Double equals asks whether two things are equal, and note carefully that it is two equals signs rather than one, because a single equals sign means something quite different in R. Greater than and less than do what you would expect. Run these and look at what comes back: not a number, but TRUE or FALSE. This looks like a small thing at the moment, but comparisons are the foundation of filtering data, which is most of what we do in Chapter 3, so it is worth being comfortable with them now.

Character

Transcript

Text in R is called a character string, and you make one by enclosing it in quotation marks, double or single. Notice in the second example that the space before the word rocks sits inside the quotes, so it is part of the string; quotation marks preserve exactly what is between them. Then look at the third box, which fails on purpose: adding two character strings is an error, because addition means nothing for text. If you want to join strings together you need different tools, and we come to those when we do the stringr package later in the course.

Anything enclosed in double (or single) quotation marks is treated as a character string.


You cannot do arithmetic on character strings


We will learn string manipulations later using the stringr package.

Missing values: NA

Transcript

Real data has holes in it, and R has a specific value for that: NA. Be clear about what it is not. It is not zero, and it is not the two-letter text NA in quotes; it is a distinct thing meaning this value is unknown. You test for it with is.na, which checks every element and returns TRUE wherever the value is missing. The first line uses c to combine four, three, NA, and nine into a vector and assigns that vector to x. Printing x lets you confirm that the missing value is stored alongside the numbers. Is dot n-a of x then returns FALSE, FALSE, TRUE, FALSE, so you can see that the third element is the missing one. Now the important behaviour: most calculations involving NA return NA, and that is correct rather than annoying, because the honest answer to what is the mean of these numbers, one of which I do not know, is that you cannot say. You can ask for the mean of what remains with na.rm equals TRUE. Here that removes the missing entry before calculating and gives sixteen divided by three, about five point three three. But read the callout, because it matters: do not reach for that out of habit. It drops observations silently, which is how you end up reporting a result computed on a different sample than the one you think you have.

R uses NA to mean “this value is missing”. It is not zero, and it is not the text "NA".


Most calculations involving a missing value return NA, because the answer genuinely is unknown:


Ask for the mean of what remains with na.rm = TRUE:


Important

Do not reach for na.rm = TRUE out of habit. It silently drops observations, so first make sure you understand why they are missing.

Assigning contents to an object

Transcript

This is the most important thing you will learn today. You assign something to a name so that you can use it again, and there are two operators that do it: the arrow, made from a less-than sign and a hyphen, and the equals sign. At the top level, for creating objects, they behave essentially the same, and the arrow is the conventional choice, which is what this course uses. Pick one and be consistent. The callout gives you the one place they genuinely differ: inside a function call, an equals sign means this is the value for this argument. When you write seq with by equals two, you are setting an argument, not creating an object called by.

  • You can assign a value (a number, a character string, a logical, and so on) to an object in R and reuse it later, using either <- or =.
object_name <- contents
object_name <- contents


  • For assignment at the top level, it makes little difference which you use, though <- is the conventional choice and the one used throughout this course. Whichever you pick, be consistent.

One place they differ

Inside a function call, = means “this is the value for this argument”, not assignment. seq(0, 10, by = 2) sets the by argument; it does not create an object called by.

Transcript

Here it is in practice: a gets the value one, b gets two. Run those two lines and then look at the environment pane in the upper right, because this is the moment that pane starts being useful. Your objects are now listed there along with their values. That pane is your window into what R currently knows about. And take the keyboard shortcut in the callout seriously: option and hyphen on a Mac, alt and hyphen on Windows, types the assignment arrow for you. You will type that arrow so often that learning the shortcut pays for itself inside a week.


Notice that these objects are now in the list of objects on the environment tab of RStudio.

Note

You can insert the assignment operator (<-) by hitting

  • Mac: Option + -
  • Windows Alt + -
Transcript

Once an object exists you can see what is inside it by typing its name and running it. That is all that evaluation means. I use the word constantly, so I want to define it once here: when I ask you to evaluate an object, I am asking you to print it so you can look at the contents. It is the simplest and most frequent thing you will do while working, and it is how you check that what you think happened has actually happened. Since a currently holds one, evaluating a prints one. If the console prefixes that output with bracket one, the bracket is an index label telling you that the displayed line begins with the first element. It is not another value stored in a.

Once objects are created, you can evaluate them on the console to see what is inside:


Note

I often ask you to evaluate an R object. That simply means printing it so you can see what it holds.

Transcript

Two more assignments, to show this works for any type. The first stores a character string in b, and notice that b was previously holding the number two, so we have just replaced it. The second stores the result of a comparison in d, and this one is worth pausing on: the right-hand side is one double-equals two, which evaluates to FALSE, and it is that FALSE which gets stored, not the comparison itself. R evaluates the right-hand side first and then assigns the result. That order matters, and it is easy to skate past.

Transcript

Three things to remember about assignment, and the last two are deliberately shown as errors so that you meet them here rather than in the middle of an assignment. First, assigning to a name that already exists silently overwrites what was there. No warning; it is simply gone. Second, a name cannot begin with a digit, so 1a is not legal. Third, you cannot use a reserved word, meaning a word the language itself needs, such as if, as an unquoted syntactic name, although backticks allow it as a non-syntactic name. Run those last two and read the errors carefully, because recognizing an error message you have seen before is a genuine and underrated skill.

Several things to remember about assignment:

  • Assigning to a name that already exists overwrites whatever was stored there before


  • Object names cannot start with a digit. Try the following:


  • Reserved words cannot be used as unquoted syntactic object names, although backticks allow them as non-syntactic names (complete list found here)

Various object types


Objects

Transcript

R is an object-oriented language, and the line on the slide captures the practical consequence: everything is an object and everything has a name. That is not merely philosophy. It means the way you work is by creating named things and then handing them to functions. The list underneath is the set of types we care about: vector, matrix, data.frame, list, and function. Notice that a function is itself an object, which sounds strange now and becomes genuinely useful in Chapter 5. The next several tabs take the first four one at a time.

  • R is an object-oriented programming language, which broadly means:

“Everything is an object and everything has a name.”

  • R has many different object types (classes)

    • vector
    • matrix
    • data.frame
    • list
    • function
Transcript

A vector is the simplest container: a sequence of elements that must all be the same type. You build one with c, which stands for combine. The first example makes a vector of numbers, the second one of characters. Now the interesting part, in the second half of the tab. What happens if you mix types? Look at the output: the numbers have turned into characters, with quotation marks around them. A vector can hold only one type, so rather than complain, R quietly promotes everything to the most general type present. That silence is the danger. When a column of numbers arrives in your analysis as text, this is usually why.

Definition

A vector is a class of object whose elements are all of the same type. Use c() to create one.

Example



What if the types are mixed?

What happens if we put elements of different types into one vector?


Every element is converted to a character. A vector can hold only one type, so R quietly promotes everything to the most general type present.

Transcript

A list is the flexible counterpart to a vector. Where a vector insists that every element be the same type, a list does not care at all: each element can be anything, including other lists, or data frames, or functions. Compare the output here against the vector example on the previous tab. When we mixed types in a vector, the numbers were converted into text. Here they are not; the number four stays a number and the character five stays a character. Nothing is coerced, because nothing needs to be. Lists become important later, when a function needs to hand you back several different things at once.

Definition

A list is a class of object whose elements may be of different types.

Example

  • A list is very flexible. It can hold essentially any kind of R object as its elements.


  • We will see more complex examples later.
Transcript

A matrix is a vector arranged in two dimensions, rows and columns, and as with a vector every element has to be the same type. You build one with the matrix function, giving it the values and telling it how many rows you want, and it works out the columns for itself. Look carefully at the first example and notice the order the values are filled in: down the first column, then down the second. That column-first filling surprises almost everyone the first time. The second example makes a matrix of characters, to show the same-type rule applies to text exactly as it does to numbers.

Definition

A matrix is a class of object whose elements are all of the same type, arranged in two dimensions (rows and columns).

Examples


Transcript

Now the one you will use constantly. A data.frame looks like a matrix, but it is better thought of as a list of columns, and the crucial difference from a matrix is that different columns may be different types. Inside data dot frame, each name-equals-value argument creates a named column. The c calls supply three values to each column, and values in the same position line up to make a row. That equal column length is what gives you a rectangle. Look at the example: nitrogen and yield are numbers, state is text, and they sit together quite happily. The first printed row, for example, joins nitrogen two hundred, yield two hundred forty, and the state Kansas. That is exactly what real data looks like, which is why this is the workhorse object of the entire course. The last bullet mentions tibble and data.table, which are variations on the same idea with some conveniences added, and we meet them later on.

data.frame is like a matrix (or a list of columns)



Several other object types behave like a data.frame:

  • tibble
  • data.table

We will talk about some of them later.

Transcript

This tab is about a habit rather than a fact, and the tabs inside it cover why it matters, how to check, and how to inspect an object visually. The short version is this: knowing what class an object is is not an academic exercise. The same function behaves differently depending on the class it is handed, and some functions simply refuse to work on some classes at all. A large share of the errors you will hit this semester come from giving a function an object it was never designed for. So when something behaves strangely, checking the class is a very good first move. On the How tab, class of yield data reports data dot frame, which is the high-level class that determines how many functions treat it. Type-of of yield data reports list, which tells you about its underlying storage and connects back to the idea that a data frame is a list of columns. Structure, written s-t-r, gives the most useful quick inspection: it reports three observations of three variables, then shows each column’s name, type, and first values. Those three functions answer related but different questions, so do not treat them as interchangeable. On the Visual inspection tab, View with a capital V opens the object in RStudio’s spreadsheet-style viewer. That is convenient for looking, but structure is faster when you need the class, dimensions, and column types together. Flip through all three inner tabs and connect the reason for checking with the diagnostic each tool provides.

It is critical to recognize the class of the objects:

  • the same function does different things depending on the class of the object to which the function is applied
  • some functions work on some object classes, but not on others

Many of the errors you will meet in R come from applying a function to an object it was never meant to handle.

Use the class(), typeof(), and str() functions to find out what you are dealing with:

You can also use the View() function to inspect an object visually:

View(yield_data)

Functions and packages


Function

Transcript

A function takes objects, does something with them, and gives you an object back. That is the whole concept, and it is worth stating that plainly because the word function carries mathematical baggage that can get in the way. The example is min: you hand it a vector of values and it hands you back the smallest one. Input, operation, output. Everything you do in R from this point onwards amounts to finding the right function and giving it the right things to work on.

A function takes R objects (a vector, a data.frame, and so on), does something with them, and returns an R object.


Example:

min() takes a vector of values as an argument and returns the minimum of all the values in the vector

Transcript

Why do we care so much about functions? Because they are the reason R is worth using at all. There are functions built into R, but far more importantly there are hundreds of thousands written by other people and shared freely, covering essentially any statistical method you might want to apply. This course is, honestly, largely a tour of the functions that make research work easier, and most of them arrive through user-written packages, which is the subject of the next slide.

  • Functions, both those built into R and those written by other users, are what make R compelling as statistical and programming software

  • Indeed, this course is largely about learning the functions that make your work easier

  • We will learn lots of functions that are made available through user-written packages

Transcript

Four functions you will use constantly, so they are worth meeting properly. seq builds a sequence, and notice it can be told either how big each step should be, using by, or how many values you want in total, using length. Both seq lines start at zero, end at one hundred, and produce the same twenty-one values. By equals five specifies the gap directly. Length equals twenty-one asks R to choose evenly spaced values, and here R partially matches the name length to the full argument name length dot out. Rep repeats a value a given number of times. Rep of ten comma five means repeat the value ten five times, so the output contains five tens. Sum adds up everything in a vector. And length tells you how many elements a vector has, which sounds trivial and turns out to be one of the things you reach for most often. There is one problem on screen that you should recognize rather than blame on either function: v-one has not been defined in this deck. If you run sum of v-one or length of v-one exactly as shown, R reports that the object is not found. Once v-one is an existing vector, sum returns the total of its elements and length returns their count. Run the working examples and keep those roles separate before you move on, because the exercise on the next tab uses them.

  • create a sequence of values


  • repeat values


  • sum values


  • find the length of a vector
Transcript

Now you use them. Three exercises, and I want you to actually type these rather than read them. First, build a vector starting at one and increasing by two up to ninety-nine, which is a direct application of seq. In spoken code, x gets seq from one to ninety-nine, with by equal to two. That gives you the fifty odd numbers in that range. Second, compute the sample mean of that vector; the formula is on the slide. Let n be length of x, then sum of x divided by n gives fifty. Third, compute the sample variance. Subtract the mean from x, which works element by element, square those deviations with caret two, add them with sum, and divide by n. The displayed formula gives eight hundred thirty-three. Read the callout carefully on that last one, because it is a trap: the formula shown divides by n, whereas R’s built-in var function divides by n minus one, so the two will not agree. Compute it directly from the formula rather than reaching for var, or you will get a number that is close and wrong. The reason for doing the arithmetic directly is to combine assignment, vectorized arithmetic, seq, sum, and length in one small problem. If you get stuck on a function name or argument, the next slide shows you how to ask R for help.

  1. Generate a vector (call it x) that starts at 1 and increases by 2 up to 99


  1. Calculate the sample mean of x

\frac{1}{n}\sum_{i=1}^n x_i


  1. Calculate the sample variance of x

\frac{1}{n}\sum_{i=1}^n (x_i-\bar{x})^2, where \bar{x} is the sample mean

Note on the formula

This formula divides by n. R’s built-in var() divides by n-1, so the two will not agree. Compute this one directly rather than reaching for var().

Getting help

Transcript

You are going to need help constantly, and there is no shame in that; it is how everybody works. The fastest route is a question mark in front of a function name, which opens its help page in the Help pane. Help pages have a reputation for being dense, and some of them earn it. R help pages follow common conventions, but their sections vary by topic. When present, two sections repay reading immediately. Usage tells you the arguments and their defaults. Examples, right at the bottom, gives you code you can run. We spend a whole slide on reading these properly in a moment.

Put a ? in front of any function name to open its help page in the Help pane:

?seq
?mean

R help pages follow common conventions, but their sections vary by topic. When present, two worth reading first are Usage, which lists the arguments and their defaults, and Examples at the very bottom, which you can copy and run.

Transcript

That works when you know the function’s name. When you do not, there are three options. Two question marks searches the help system for a phrase rather than a name. Searching the web works genuinely well, because R is popular enough that somebody has almost certainly asked your question already; phrase it as r how to and then what you want. And the practical tip in the third bullet is worth taking: include the package name in your search, because dplyr filter multiple conditions gets you a useful answer where filter multiple conditions does not.

  • ??regression searches the help system for a phrase rather than a function name
  • Searching the web for “r how to …” works well, because R is popular enough that someone has almost certainly asked already
  • Include the package name in your search, for example “dplyr filter multiple conditions”
Transcript

When something goes wrong, R prints an error, and the single most useful habit you can build this semester is reading it before you do anything else. It usually names the function that failed and says what it objected to. Run the example here, which asks R to sum a character string, and look at what comes back. The message says the argument has the invalid type character. That is useful evidence: sum exists and was called, but the object you supplied is not a numeric or otherwise summable input. Then read the callout and take it seriously: pasting an error message into a search engine is not cheating and it is not a sign that you are struggling. It is what practising researchers do every day of the week.

When something goes wrong, R prints an error. Read it before doing anything else: it usually names the function that failed and what it objected to.

Note

Copying the error message into a search engine is a perfectly respectable way to solve a problem, and it is what practising researchers do daily.

Transcript

We are going to spend a whole slide on how to read a help page, because it is a skill that pays off for the rest of your career and almost nobody is ever taught it. The important structural fact is on this tab: R help pages follow common conventions, but their sections vary by topic. Once you understand those conventions, you can navigate the pages more easily. On the seq page, three sections do the real work, Usage and Arguments and Examples, and we take them one at a time using seq, which you have already met.

Running ?seq opens the page shown in the next tabs. R help pages follow common conventions, but their sections vary by topic, so learning those conventions makes the pages easier to navigate.

?seq


The three sections you will actually use are Usage, Arguments, and Examples. We take them one at a time, using seq() as the example.

Transcript

Right at the top is the Description, which is a sentence or two saying what the function does. For seq it is simply: generate regular sequences. That is usually all you need in order to decide whether you are in the right place. Treat this section as a filter. If the description does not match what you want, close the page and keep looking rather than reading on. If it does match, go straight to Usage.

At the very top, the Description states in a sentence or two what the function does. Run

?seq

and the first thing on the page is:


Generate regular sequences.


That is usually enough to decide whether this is the function you want. If it is not, move on; if it is, read Usage next.

Transcript

Usage is the most useful section on the page and the one worth learning to read properly. It shows how the function is called, with every argument and its default value. Read it like this. Each name-equals-value pair is an argument together with the value you get if you do not supply it, so if you say nothing about from, it is one. To is the endpoint and also defaults to one. By is the increment, and the expression shown as its default connects the endpoints to length dot out when you request a particular number of values. Null for length dot out means that no output length has been requested. Along dot with gives another route: supply an existing object there and seq makes a sequence with one position for each of its elements. Arguments are matched by position when you do not name them and by name when you do, which is why seq of zero comma ten means from zero to ten. And the three dots mean the function accepts further arguments, which you can happily ignore at first. The callout explains why a function listing five arguments works fine when you supply two: you only ever need to override the defaults you want to change. The dense-looking Usage line is not code you are expected to memorize. It is a compact map that tells you what can be supplied and what R will assume.

Usage is the single most useful section. It shows how the function is called and, crucially, its arguments and their default values.

seq(from = 1, to = 1, by = ((to - from)/(length.out - 1)),
    length.out = NULL, along.with = NULL, ...)

Read it like this:

  • Each name = value is an argument together with its default. If you do not supply from, it is 1; if you do not supply length.out, it is NULL.
  • Arguments are matched by position when you do not name them, or by name when you do. So seq(0, 10) means from = 0, to = 10.
  • ... means the function accepts further arguments (here, passed on to methods). You can ignore it at first.

Defaults are your friend

You only need to supply the arguments whose defaults you want to change. That is why seq(0, 10) works even though the function lists five arguments.

Transcript

Arguments goes through each one in turn and says what it means and what sort of value it expects. For seq: from is where the sequence starts, to is where it ends, by is the step size, and length.out is how many values you want. Now notice the observation underneath, because that is the real lesson of this tab. There is more than one way to describe the same sequence: you can say how big the steps are, or you can say how many values you want. You would never have guessed that from the function’s name. Reading Arguments is how you discover options you did not know existed.

Arguments explains, one by one, what each argument means and what kind of value it expects.

  • from: the starting value of the sequence
  • to: the end value of the sequence
  • by: the increment between consecutive values
  • length.out: the desired number of values


Notice there is more than one way to describe the same sequence: you can say how big each step is (by) or how many values you want (length.out). Reading Arguments is how you discover options like this.

Transcript

Scroll to the very bottom of any help page and you reach Examples, which is runnable code written by the person who made the function. Copying one of those and running it is very often the fastest way to understand what a function does. The two examples here show the two routes we just discussed: stepping by two, and asking for eleven evenly spaced values. The callout gives you a habit worth forming, and it is the opposite of what people naturally do. When you meet a new function, go to Examples first, run one, and then look back up at Usage to see which arguments it used.

Scroll to the very bottom and you reach Examples—runnable code the author provided. Copying an example and running it is often the fastest way to understand a function.

A habit worth forming

When you meet a new function, jump straight to Examples, run one, then look back up at Usage to see which arguments it used.

Transcript

Now practise that on a function whose documentation you have not seen. Open the help page for rep and answer the three questions by reading rather than guessing. What does times do, what does each do, and then predict the output of the two lines before you run them. That prediction step is the entire point of the exercise. If your prediction is right, you have read the page correctly. If it is wrong, you have found exactly the gap between what you assumed and what the documentation actually said, and that is worth more than getting it right first time. Here is the distinction you should recover from the page. Times equals three repeats the whole vector three times, so the first line returns one, two, one, two, one, two. Each equals three repeats every individual element three times before moving on, so the second returns one, one, one, two, two, two. The same six values appear, but their order records which argument did the repeating.

Open the help page for rep() and use Usage and Arguments to answer these—read, do not guess.

?rep
  1. What does the times argument do?
  2. What does the each argument do?
  3. Predict the output of each line below, then run it to check.

Package

Transcript

Here is the analogy I would like you to carry with you. Your R environment is a workspace, and a package is a drawer of specialized tools for one particular kind of job. The list on the slide is a preview of the semester: dplyr and data.table for wrangling data, ggplot2 for visualization, and sf, raster, and stars for spatial data. You do not need to know what any of them do yet. The point is that when you need to do a new kind of work in R, the answer is almost always that somebody has already built the drawer for you.

A package is a drawer in your workspace (the R environment) holding specialized tools (functions) for a particular set of tasks.


Example packages:

  • dplyr (data wrangling)
  • data.table (data wrangling)
  • ggplot2 (data visualization)
  • sf (spatial vector data handling)
  • raster (spatial raster data handling)
  • stars (spatiotemporal data handling)
Transcript

Two steps, and keeping them separate in your head prevents a lot of confusion. First you install the package, using install.packages with the name in quotes, which downloads it onto your computer. The first box is a template, and the second replaces package name with ggplot2 to show a real installation call. The quotation marks matter because install dot packages expects the package name as character text. Then, to actually use it, you load it with library, which brings that drawer into your current workspace. In the library call shown, ggplot2 is written as the package name without quotation marks. Loading does not download the package, so it works only after installation has succeeded. Now read the callout, because this is a genuine stumbling block: you install once per computer, but you load in every new session. And crucially that includes every time you render a Quarto document, because rendering starts a fresh session. That single fact is the source of a great many could not find function errors.

  • Before you can use the tools (functions) in a drawer (package), you have to obtain the drawer (install the package). Install one like this:
install.packages("package name")


  • For example,
install.packages("ggplot2")


  • You then bring the drawer (package) into your workspace (the R environment) with the library() function:
library(ggplot2)


  • You can now use the tools (functions) that drawer contains.

Install once, load every time

You install a package only once on a given computer. You have to load it with library() in every new R session, and that includes every time you render a Quarto document.

Working with R (or any computer programs)

Transcript

I want to close this section with a way of thinking about what you are doing when you program. You are the architect: you hold the picture of the finished thing, but you cannot lay the bricks yourself. R is your builder, and it will build any piece perfectly, provided you give it the right tools and the right instructions. But it is a peculiar builder. Give it the wrong tool, or an instruction that does not quite parse, and it stops and reports an error. It will never guess what you meant, and it will never quietly work around a problem for you. Your job is supplying correct instructions and fixing them when they turn out to be wrong, and that fixing is what debugging means. It is not a sign of failure. It is the job.

  • You are the architect. You hold the blueprint for the finished product, but you cannot build the individual pieces yourself.

  • You work with a single builder (R), who can build any piece perfectly if given the right tools and the right instructions .

  • This builder is peculiar. Given the wrong tools, or an instruction that does not make sense, they stop and report an error. They will never guess at what you meant or work around the problem on their own.

  • Your job is to supply the right tools and instructions, and to correct them when you discover you have made a mistake. That correcting is called debugging.

A bit more on vector, matrix, list, and data.frame


Vector

Transcript

We are going back over the four object types in a bit more depth, starting with vectors, and this first tab simply sets up two of them to play with. a holds the numbers one through five, and b is assigned a, which makes b a copy of those same five numbers. Run these before you move on, because every example in the following tabs uses them. There is nothing conceptually new here; these are just the ingredients.

Let us define two vectors to work with.

Transcript

Now add, subtract, multiply, and divide the two vectors, and look carefully at what comes back each time. Every result is itself a vector of five numbers. That is the point, and it is what the callout is telling you: arithmetic on vectors happens element by element. The first element of a is combined with the first element of b, the second with the second, and so on down the line. Because a and b contain the same values, addition doubles each position, subtraction produces five zeros, multiplication produces the squares one, four, nine, sixteen, twenty-five, and division produces five ones. Those outputs are a quick check that you are pairing corresponding positions. This is called vectorization, and it is one of the things that makes R pleasant to use, because in many other languages you would have to write a loop to achieve the same thing.

Note

Vector arithmetic operations happen element by element!

Transcript

To get at part of a vector you use square brackets with a position inside them. a bracket two gives you the second element. The next line applies the same rule to b, so b bracket three gives you its third element. And you are not limited to one at a time: put a vector of positions inside the brackets and you get several elements back, so a bracket c of one comma two gives you the first and second. The final example asks b for positions one and five and returns those two values. Notice the pattern here, because it generalizes: whatever goes inside the brackets describes which elements you want. R counts positions from one, not zero, which is why bracket one means the first element. That idea carries straight over to matrices and data frames, where the brackets simply gain more positions.

To access element(s) of a vector, you use [] like below:


You can access multiple elements of a vector

Matrix

Transcript

Two ways to build a matrix, shown side by side. The first fills a three-by-two matrix entirely with the value two, and its arguments are the value, the number of rows, and the number of columns. The second takes an actual vector of six values and asks for three rows, leaving R to work out that there must therefore be two columns. Run both and look at how B is laid out, because it fills column by column rather than row by row. Keep A and B in your environment, since the next three tabs both use them.

Transcript

Adding and multiplying matrices with the ordinary plus and asterisk works element by element, exactly as it did for vectors. Look at A times B and check a couple of the entries by hand: the value in the first row and first column of the result is the product of the corresponding entries in A and B. This is worth being explicit about, because if you have done any linear algebra, the asterisk is almost certainly not doing what you expect it to do. The proper matrix product is on the next tab.

Transcript

Two genuine matrix operations here. t transposes, turning rows into columns. And the percent-asterisk-percent operator is real matrix multiplication, the linear algebra kind, as opposed to the element-by-element multiplication on the previous tab. Look carefully at the example: we transpose B first so that the dimensions line up, because matrix multiplication requires the number of columns in the first to match the number of rows in the second. If you meet a non-conformable arguments error later in the course, this is the rule you have broken.

Transcript

Accessing a matrix uses the same square brackets as a vector, but now there are two positions inside, separated by a comma: rows first, then columns. So A bracket one comma two is the first row, second column. As with vectors you can ask for several at once by putting a vector into either position. In the second example, c of one comma three in the row position selects rows one and three, while the two after the comma keeps only column two. And the third example is the one to remember: leaving a position empty means give me all of them, so A bracket one comma nothing hands you the entire first row. That empty-means-everything convention comes up constantly once we get to data frames.

To access elements of a matrix you use [], just as for a vector, but now there are two positions inside the brackets:

matrix[indices for rows, indices for columns]


Examples

List

Transcript

Back to lists, now with something more realistic in one. This list holds three completely different things: a matrix, a character vector, and the data frame we built earlier. That is the flexibility we talked about, actually being used. The other new thing here is that each element has been given a name, using name equals value inside the list call. Look at how the printed output labels them. Those names are what make the dollar-sign access on the third tab possible, and in practice you should almost always name your list elements.

As mentioned earlier, a single list can hold objects of any type.

Note that each element has a name.

Transcript

Lists have their own bracket rules, and this is a classic source of confusion, so let us be precise about it. Double square brackets give you a single element, the thing itself. Single square brackets give you back a sub-list, even when you asked for only one thing. So double brackets two hands you the actual second element, while single brackets with a vector of positions hands you a smaller list containing those elements. The rule of thumb: double brackets to reach in and take something out, single brackets to take a slice of the list that is still a list.

To access elements of a list, use [[]] for a single element and [] for more than one.

Example: single element


Example: multiple elements

Transcript

The third way in, and in practice the one you will use most, is the dollar sign, which works whenever an element has a name. names shows you what those names are, and then dollar b gets you the element called b. Compare this against the previous tab: dollar b and double brackets two give you the same thing here, but the dollar sign version says what you actually mean rather than relying on position, so it keeps working even if the order changes. This is the syntax you will be using on data frame columns constantly from Chapter 3 onwards.

You can also use the $ operator to access a single element of a list, as long as that element has a name.

data.frame

Transcript

Now the object you will spend the rest of the course inside. Three things to hold onto. It is the most common type we use, by a wide margin. Technically it is a special kind of list whose elements are vectors that all happen to have the same length, and that equal length is what gives it its rectangular, matrix-like shape. And because of that dual nature it inherits properties of both a list and a matrix, which is exactly why the next tab shows two different ways of getting at its contents. Run mtcars to see a real one. In the printed output, each row is a car model and each named column is a measured variable such as miles per gallon, cylinders, or gears. The aligned rows show what equal-length column vectors look like when R presents them as one rectangular data frame. All the displayed mtcars columns are numeric, but that is a feature of this dataset, not a requirement of data frames.

data.frame (and its relatives)

  • is the most common object type we use.
  • is a special kind of list whose elements are vectors of equal length, which gives it a matrix-like shape
  • shares properties of both the matrix and the list
Transcript

And here is that dual nature in action. The list-like way uses the dollar sign with a column name, so mtcars dollar gear hands you that entire column as a vector, one gear count for every car. The matrix-like way uses square brackets with a row position and a column position. Mtcars bracket one comma two selects the first row and second column, which the label identifies as cylinders, and the value returned is six. Both are correct, and which one you reach for depends on whether you are thinking of the object as a collection of named columns or as a rectangle of values. The line in red is a promise: we are going to spend a great deal of time doing exactly this kind of work with the tidyverse, and it will be considerably more pleasant than square brackets.

Accessing parts of a data.frame works like accessing elements of a matrix or a list.

Examples

list-like: access the gear column by name


matrix-like: 1st row, 2nd column (cyl)


We will spend lots of time on how to do data wrangling on data.frames using the tidyverse package!

Next class: Quarto