Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

1Objectives

By the end of this lesson you will be able to:

  1. Create and reassign objects using <-, and explain R’s basic data types.

  2. Build, index, and compute on vectors.

  3. Inspect a data frame’s structure, size, and columns.

  4. Call functions with positional and named arguments.

  5. Find help for any R function using ?, help(), and args().

2Objects and assignment

Everything in R is an object — a name that points to a value stored in memory. You create one with the assignment arrow, <- (typed as < then -; think of it as “put this value into this name”):

x <- 5
x
[1] 5

The [1] in front just means “this is the first (and here, only) value printed” — you’ll see it before every printed vector in this book. Typing an object’s name by itself, as above, prints its current value.

Objects can be reassigned — the new value simply replaces the old one:

x <- x + 1
x
[1] 6

Naming rules: an object name must start with a letter, and can contain letters, numbers, ., and _. R is case-sensitiveCoffee and coffee are two different objects. Use short, descriptive, lowercase names (sleep_hours, not x7 or Data).

3Basic data types

Every value in R has a type, which class() tells you:

class(5)
class("cat person")
class(TRUE)
class(5L)
[1] "numeric"
[1] "character"
[1] "logical"
[1] "integer"
TypeExampleNotes
numeric5, 3.14, -2any real number (decimal or whole)
integer5La whole number; the L forces integer type — rare that you need it
character"cat person"text, always in quotes
logicalTRUE, FALSEthe result of a yes/no comparison, e.g. 5 > 3

You will rarely need to force a type yourself — R and the functions you call (read.csv() in L06, for instance) usually figure it out. Knowing the four types matters mainly for reading error messages later (L14) that mention “non-numeric argument” or similar.

4Vectors: more than one value in one object

A vector holds several values of the same type in order. Build one with c() (“combine”):

coffee <- c(0, 2, 1, 3, 0)
coffee
length(coffee)
[1] 0 2 1 3 0
[1] 5

Arithmetic on a vector applies to every element at once — this is called being vectorized, and it’s why R rarely needs the loops you might expect from other languages:

coffee * 2
sum(coffee)
mean(coffee)
[1] 0 4 2 6 0
[1] 6
[1] 1.2

coffee * 2 doubled every entry; sum() added them all; mean() divided that sum by length(coffee). (mean(coffee) here is base R’s version, which works on a bare vector. L05 introduces mosaic’s mean(~ coffee, data = ...) form, which reads a whole data frame at once — both exist, and you’ll use each where it fits.)

Indexing — pulling out specific elements — uses square brackets [ ] with the position you want (R counts from 1, not 0):

pets <- c("cat", "dog", "cat", "fish", "dog")
pets[1]
pets[2:3]
coffee[coffee > 1]
[1] "cat"
[1] "dog" "cat"
[1] 2 3

pets[1] is the first element. pets[2:3] uses the range 2:3 to grab the 2nd through 3rd elements. coffee[coffee > 1] is a logical index: R first evaluates coffee > 1 element-by-element (giving TRUE/FALSE for each of the 5 entries), then keeps only the values where that’s TRUE. This pattern — “give me the values of X where some condition holds” — is one of the most useful things you’ll do with a vector all semester.

5Data frames: R’s spreadsheet

A data frame is a table: rows are cases (here, students), columns are variables. It’s how almost every dataset in this course arrives. L06 covers importing data frames in full; for now, read one in with read.csv() so you have something real to inspect (this is the running survey_sim dataset described on the book’s front page):

survey <- read.csv("data/survey_sim.csv")
str(survey)
'data.frame':	120 obs. of  9 variables:
 $ student_id : chr  "S001" "S002" "S003" "S004" ...
 $ class_year : chr  "Junior" "Sophomore" "Sophomore" "Senior" ...
 $ major_area : chr  "Nursing" "STEM" "Other" "STEM" ...
 $ pet        : chr  "Dog person" "Cat person" "Cat person" "Cat person" ...
 $ coffee_cups: int  0 2 2 1 0 2 2 2 2 0 ...
 $ sleep_hours: num  5.2 6.9 6.2 6.4 6.7 8.7 6.9 6.8 5.9 7 ...
 $ commute_min: int  34 18 30 14 19 28 13 17 13 25 ...
 $ study_min  : int  309 91 95 309 387 215 200 278 311 304 ...
 $ exam_score : num  60.2 39.7 48.6 61.1 86.1 52 65.2 65.7 61.8 54.4 ...

str() (“structure”) is the fastest way to get oriented in a new data frame: 120 observations (rows), 9 variables (columns), each with its type (chr = character, int = integer, num = numeric) and a preview of its first values. Notice class_year and pet came in as plain text (chr), not a special “category” type — modern R (4.0+) leaves text as text by default when you read.csv(), which is almost always what you want; you convert to a category (a factor) only when you need one, which L07 and later lessons will do for plots and grouped summaries.

A few more inspection basics:

nrow(survey)
ncol(survey)
dim(survey)
names(survey)
[1] 120
[1] 9
[1] 120   9
[1] "student_id"  "class_year"  "major_area"  "pet"         "coffee_cups"
[6] "sleep_hours" "commute_min" "study_min"   "exam_score"

nrow()/ncol() give rows and columns separately; dim() gives both at once (rows first, then columns); names() lists the column names — you’ll need these exact names constantly, so names() is worth running the moment you meet a new dataset.

head() shows the first few rows as an actual table (tail() shows the last few, the same way):

head(survey, 3)
  student_id class_year major_area        pet coffee_cups sleep_hours
1       S001     Junior    Nursing Dog person           0         5.2
2       S002  Sophomore       STEM Cat person           2         6.9
3       S003  Sophomore      Other Cat person           2         6.2
  commute_min study_min exam_score
1          34       309       60.2
2          18        91       39.7
3          30        95       48.6

Pulling out one column uses $, giving you back a plain vector you can index or compute on exactly like the coffee vector above:

survey$sleep_hours[1:5]
mean(survey$sleep_hours)
[1] 5.2 6.9 6.2 6.4 6.7
[1] 6.7875

6Calling functions: positional vs. named arguments

A function is a named, reusable operation — mean(), sum(), and read.csv() are all functions. Every function takes arguments, and R lets you supply them two ways: by position (order matters) or by name (order doesn’t):

round(mean(survey$sleep_hours), 2)
round(mean(survey$sleep_hours), digits = 1)
[1] 6.79
[1] 6.8

Both lines round the same number; the first supplies 2 positionally as round()'s second argument, the second names it explicitly (digits = 1). Naming your arguments is more typing but harder to get wrong, especially once a function takes several arguments — this book uses named arguments (like data = ) whenever it helps clarity, which is most of the time from L05 onward.

7Getting help

Three ways to find out what a function does and what arguments it takes, from fastest to most detailed:

args() in action, for two functions you just used:

args(round)
args(mean.default)
function (x, digits = 0, ...) 
NULL
function (x, trim = 0, na.rm = FALSE, ...) 
NULL

Read round’s output as: “round() takes x (the number to round) and digits (how many decimal places, defaulting to 0 if you don’t say).” The ... you’ll see in many functions’ argument lists means “and possibly more arguments — see the full help page.” The trailing NULL is not useful output itself; it’s just what args() always prints last — ignore it.

8Summary