[1] "no"
[1] 7
Chapter 5: An Overview of the R Language
Shih Chien University
2026-08-03
Learning a computer language is much like learning a spoken one (only simpler). A tourist can survive on memorized phrases; Chapter 3 gave you those phrases. But to speak fluently you need grammar — verb conjugation, sentence structure. This chapter is R’s grammar lesson, built on four ideas:
Master these and the detailed syntax of Chapter 6 will feel inevitable rather than arbitrary.
R code is a series of expressions: assignments, conditionals, arithmetic, and more — each evaluated to produce a value:
Expressions are composed of objects and functions, and may be separated by newlines or semicolons:
All R code manipulates objects — “things” represented by the computer. Numeric vectors, character vectors, lists, and functions are all objects:
[1] 1 2 3 4 5
[1] "This is an object too"
[[1]]
[1] 1 2 3 4 5
[[2]]
[1] "This is an object too"
[[3]]
[1] "this whole thing is a list"
function (x, y)
{
x + y
}
Formally, variable names in R are symbols. Assigning a value to a name binds the symbol to the object in the current environment — and, a touch tautologically, an environment is the set of symbols defined in a given context:
Chapter 8 treats symbols and environments in full; for now, just remember that a name and the thing it names are different objects.
A function takes input objects (its arguments) and returns an output object. Every statement — setting variables, doing arithmetic, looping — can be written as a function call. The book’s demonstration starts with a humble vector:
[1] "cow" "chicken" "pig" "duck"
That bracket assignment is parsed into a call to the function [<- (the full expansion also rebinds the result: animals <- `[<-`(animals, 4, "duck")). Calling it directly:
[1] "cow" "chicken" "pig" "duck"
(Two subtle differences: called directly the result is auto-printed — and without the rebinding step, animals itself is left unchanged.)
In practice you would never write `[<-`(animals, 4, "duck") — bracket notation is far easier to read. But knowing the function is there means you can inspect its code, read its help page, or write methods with the same name for your own classes (Chapter 10). More pretty-vs-functional pairs:
[1] 7
[1] 7
[1] "oranges are better"
[1] "oranges are better"
In assignment statements, most objects are immutable: R copies the object, not merely a reference to it. (Immutability is a virtue — it prevents whole categories of errors, e.g., in multithreaded programs.)
This holds for vectors, lists, and most other primitive objects.
Arguments are copied as well. This function sets the ith element of x to 4 — and accomplishes nothing visible:
[1] 10 11 12 13
Technically, the interpreter copies the object bound to w and binds the symbol x to the copy; the modification happens only inside the function’s context. (Mutable objects and pass-by-reference become possible with environments — Chapter 8.)
Note
Semantics vs. performance. R behaves as if every assignment copies, but often modifies objects in place — e.g., v <- 1:100; v[50] <- 27 alters the vector without copying it. Identical meaning, much better speed. Details live in the R Internals guide.
Not just data: functions, symbols, even expressions are objects. A function name is really a symbol pointing at a function object (a relationship itself stored in an environment object). The same symbol can hold a number one moment and a function the next:
[1] 1
Error in `x()`:
! 沒有這個函式 "x"
function (i)
i^2
[1] 4
You can even write R code that constructs new functions — in principle, a function that rewrites its own definition.
NA (“not available”) represents missing values — common in loaded text data, and substituted for database NULLs. Expanding a structure beyond its defined values fills the new cells with NA:
Numbers too big to represent become infinity, signed accordingly — also the result of dividing by zero:
Computations that make no sense yield NaN (“not a number”):
The symbol NULL always points to one special object: the null object.
NULL is not the same as NA, Inf, -Inf, or NaN — it is not a value at all, but the absence of one.Call a function with the “wrong” type and R tries to coerce the value so the call still works. Two mechanisms operate automatically:
TRUE → 1, FALSE → 0.raw objects are not converted to other types.I() (the AsIs function) — see ?AsIs.Note
Why so permissive? Strongly typed languages (Java) raise exceptions instead of converting. John Chambers, S’s designer, recalled that early S “made as many cases work as possible,” but the later, formal conclusion was that converting richer types to simpler ones in all situations breeds confusing, untrustworthy results. In daily practice — numeric vectors of one type — coercion rarely bites.
R is an interpreted language: the interpreter executes your expressions directly, with no compile step (unlike C, C++, Java; like LISP, Perl, JavaScript). For each expression, the interpreter:
Example: typing x <- 1 becomes the call `<-`(x, 1), which binds 1 to x in the current environment and returns 1.
With x bound to 1, consider:
The interpreter parses the line as an if-then-else structure, evaluates the condition (x > 1) first — false — and therefore never evaluates "orange"; it evaluates the expression after else and returns "apple". In special cases like this, not all arguments are evaluated — which is why if cannot be an ordinary function. And whatever an expression returns at the console gets handed to print.
Some functionality lives inside the R system itself:
.Internal (or its sibling .External) — e.g., the graphics workhorse, which nowadays goes through .External.graphics:function (xy, type, pch = par("pch"), lty = par("lty"), col = par("col"),
bg = NA, cex = 1, lwd = par("lwd"), ...)
{
if (is.null(type))
type <- "p"
type <- as.character(type)
if (length(type) != 1L || !nzchar(type) || is.na(type))
stop(gettextf("invalid plot type"))
if (nchar(type) > 1L)
warning(gettextf("plot type '%s' will be truncated to first character",
type))
t <- substr(type, 1L, 1L)
if (!isTRUE(t %in% c("l", "o", "b", "c", "s", "S", "h", "p",
"n")))
stop(gettextf("invalid plot type '%s'", t))
invisible(.External.graphics(C_plotXY, xy, t, pch, lty, col,
bg, cex, lwd, ...))
}
<bytecode: 0xa43208ba0>
<environment: namespace:graphics>
.Internal’s calling overhead is too high, functions are implemented entirely internally via .Primitive — reserved for a few performance-critical basics:Because R expressions are R objects, you can parse — or partially evaluate — expressions and inspect the result. The quote() function parses its argument but does not evaluate it, returning a language object:
…but convert the language object to a list and the structure appears — this is the expression’s parse tree:
[[1]]
`if`
[[2]]
x > 1
[[3]]
[1] "orange"
[[4]]
[1] "apple"
Apply typeof to every element to label the tree (here using lapply — and thanks to coercion, the as is optional):
[[1]]
[1] "symbol"
[[2]]
[1] "language"
[[3]]
[1] "character"
[[4]]
[1] "character"
Observations: the else keyword vanishes in parsing; the first element is a symbol referring to the if function — so even special syntax becomes function name first, arguments after, exactly like any call. For constants, the list has a single item: as.list(quote(1)).
The bracket lookup x[2] and its functional twin parse to the identical tree:
[[1]]
`[`
[[2]]
x
[[3]]
[1] 2
[[1]]
`[`
[[2]]
x
[[3]]
[1] 2
The translation is irreversible — both collapse to one tree — but deparse turns a parse tree back into properly formatted R code, choosing the pretty syntax:
Tip
Tools to carry through the book: quote, substitute, typeof, class, and methods let you watch the interpreter parse and dispatch. When R surprises you, these are your microscope.
Copyright. These slides are adapted from R in a Nutshell: A Desktop Quick Reference (2nd ed.) by Joseph Adler, O’Reilly Media. All rights reserved by the original author and publisher.
Non-commercial use only. These materials are strictly for educational purposes and may not be used for commercial gain.
Attribution. Any reproduction, distribution, or use of these materials must properly credit the original source.
R in a Nutshell: A Desktop Quick Reference