Chapter 6 R Syntax
Frustration is natural when you start programming in R. R is a stickler for punctuation, and even one character out of place will cause it to complain. But while you should expect to be a little frustrated, take comfort in that it is both typical and temporary: it happens to everyone, and the only way to get over it is to keep trying.
To understand computations in R, two slogans are helpful:
- Everything that exists is an object.
- Everything that happens is a function call.
6.1.1 Arithmetic operators
In its most basic form, R can be used as a simple calculator. Consider the following arithmetic operators:
|^ or **||exponentiation|
|x %% y||modulus (remainder)|
1 / 200 * 30 #>  0.15 (59 + 73 + 2) / 3 #>  44.7 5 %% 2 #>  1
But when we do this, none of our results are saved for later use.
6.1.2 Assigning Variables
An essential part of programming is creating objects (or variables).1 Variables are names for values.
A variable is created when a value is assigned to it. We do that with
x <- 3
<- is called the assignment operator. It assigns values on the right to objects on the left, like this:
object_name <- value
So, after executing
x <- 3, the value of
3. The arrow can be read as 3 goes into
NB: Do not use
= for assignments. It will work in some contexts, but it will cause confusion later. There will be other scenarios where you will use
= - we will discuss these later on.
We can use variables in calculations just as if they were values.
x <- 3 x + 5 #>  8
Inspect objects to display values.
In R, the contents of an object can be printed by simply executing the object name.
x <- 3 x #>  3
Whitespace makes code easier to read.
Notice that we surrounded
<- with spaces. In
R, white space is ignored (unlike Python). It is good practice to use spaces, because it makes code easier to read.
experiment<-"current vs. voltage" # this is bad experiment <- "current vs. voltage" # this is better
6.1.3 Variable Names
Object names can only contain letters, numbers,
You want your object names to be descriptive.
x is not a good variable name (sorry!). You will also need a convention for multiple words. I recommend snake_case, where you separate lowercase words with
i_use_snake_case otherPeopleUseCamelCase some.people.use.periods And_aFew.People_RENOUNCEconvention
Let's make an assignment using snake_case:
r_rocks <- 2 ^ 3
And let's try to inspect it:
r_rock #> Error in eval(expr, envir, enclos): object 'r_rock' not found R_rocks #> Error in eval(expr, envir, enclos): object 'R_rocks' not found
R is case-sensitive!
Use the TAB key to autocomplete.
Because typos are the absolute worst, we can use R Studio to help us type. Let's inspect
r_rocks using RStudio’s tab completion facility. Type "r_", press TAB, add characters until you have a unique prefix, then press return.
r_rocks #>  8
Challenge 1: Making and Printing Variables
Make 3 variables: name (with your full name), city (where you were born), and year (when you were born).
Challenge 2: Swapping Values
Draw a table showing the values of the variables in this program after each statement is executed.
In simple terms, what do the last three lines of this program do?
lowest <- 1.0 highest <- 3.0 temp <- lowest lowest <- highest highest <- temp
Challenge 3: Predicting Values
What is the final value of
position in the program below? Try to predict the value without running the program, then check your prediction.
initial <- "left" position <- initial initial <- "right"
Challenge 4: Syntax
Why does the following code fail?
age == 31
And the following?
31 <- age
R has a large collection of built-in functions that helps us do things. When we use a function, we say we are calling a function.
function_name(arg1 = val1, arg2 = val2, ...)
Here are some helpful built-in functions:
my_var <- c(1, 5, 2, 4, 5) sum(my_var) #>  17 length(my_var) #>  5 min(my_var) #>  1 max(my_var) #>  5 unique(my_var) #>  1 5 2 4
An argument is a value that is passed into a function. Every function returns a result.
Let’s try using
seq(), which makes regular sequences of numbers. While we are at it, we will learn more helpful features of RStudio.
se and hit TAB. A popup shows you possible completions. Specify
seq() by typing more (a "q") to disambiguate, or by using ↑/↓ arrows to select. Notice the floating tooltip that pops up, reminding you of the function’s arguments and purpose.
Press TAB once more when you have selected the function you want. RStudio will add matching opening (
() and closing (
)) parentheses for you. Type the arguments
1, 10 and hit return.
seq(1, 10) #>  1 2 3 4 5 6 7 8 9 10
How many arguments did we pass into the
6.2.2 Store Function Output
Notice that, when we called the
seq function, nothing changed in our environment. That is because we did not save our results to an object. Let's try it again by assigning a variable:
y <- seq(1, 10) y #>  1 2 3 4 5 6 7 8 9 10
6.2.3 Argument Restrictions and Defaults
Let's use another function, called
round(60.123) #>  60
round must be given at least one argument. Moreover, it must be given things that can be meaningfully rounded.
Functions may have default values for some arguments.
round will round off any number to zero decimal places. But we can specify the number of decimal places we want.
round(60.123) #>  60 round(60.123, digits = 2) #>  60.1 round(60.123, 2) #>  60.1
6.2.4 Documentation and Help Files
How do we know what kinds of arguments to pass into a function? Every built-in function comes with _documentation.
?+ object opens a help page for that specific object.
??+ object searches help pages containing the name of the object.
All help files are structured the same way:
- The Arguments section tells us exactly what kind of information we can pass into a function.
- The Value section explains what the output of the function is.
- The Examples section contains real examples of the function in use.
Challenge 1: What Happens When
Explain, in simple terms, the order of operations in the following program: when does the addition happen, when does the subtraction happen, when is each function called, etc.
What is the final value of
radiance <- 1.0 radiance <- max(2.1, 2.0 + min(radiance, 1.1 * radiance - 0.5))
Challenge 2: Why?
Run the following code.
rich <- "gold" poor <- "tin" max(rich, poor)
Using the help files for
max, explain why it returns the result it does.
6.3 Data Types
Every value in a program has a specific type. In R, those types are called "classes", and there are 4 of them:
- Character (text or "string").
- Numeric (integer or decimal).
- Integer (just integer).
- Logical (TRUE or FALSE booleans).
|2 (Must add a
6.3.1 What Is that Type?
R is dynamically typed, meaning that it "guesses" what class a value is. Every piece of information in R has a type!
Use the built-in function
class() to find out what type a value has.
class(3) #>  "numeric" class(3L) #>  "integer" class("Three") #>  "character" class(T) #>  "logical"
This works on variables as well. But remember: the value has the type --- the variable is just a label.
three <- 3 class(three) #>  "numeric" three <- "three" class(three) #>  "character"
A value's class determines what the program can do to it.
3 - 1 #>  2 3 - "1" #> Error in 3 - "1": non-numeric argument to binary operator
We just learned we cannot subtract numbers and strings. Instead, use
as. + name of class as a function to convert a value to a specified type.
3 - as.numeric("1")
This is called
coercion. Here is another example:
my_var <- "FALSE" my_var #>  "FALSE" as.logical(my_var) #>  FALSE
What difference did you notice?
6.3.3 Other Objects
There are a few other "odd ball" types in R:
NA are missing values.
Missing values are specified with
NA will always be coerced to the correct type if used inside
x <- c(NA, 1) x #>  NA 1 typeof(NA) #>  "logical" typeof(x) #>  "double"
Inf is infinity.
You can have either positive or negative infinity.
1/0 #>  Inf 1/Inf #>  0
NaN means "not a number." It is an undefined value.
0/0 #>  NaN
Challenge 1: Making and Coercing Variables
- Make a variable
yearand assign it as the year you were born.
- Coerce that variable to a string and assign it to a new variable
- Someone in your class says they were born in 2001. Really? Really. Find out what your age difference is, using only
Challenge 2: Fix the Code
Change the following code to make the output
val_1 <- F val_2 <- "F" class(val_1) == class(val_2) #>  FALSE
6.4 Boolean Expressions
Boolean expressions are logical statements that are either true or false. For our purposes, we will often use Boolean expressions to compare quantities. For instance, the Boolean expression
1 < 2 is true, whereas the Boolean expression
1 > 2 is false.
When you type a Boolean expression in R, R will output
TRUE if the expression is true and
FALSE if the expression is false.
6.4.1 Boolean Operators
||less than or equal to|
||greater than or equal to|
||exactly equal to|
||not equal to|
||is an item of a set|
Note that we use a double equal sign
== to check whether two values are equal. Typing
a = b would set the value of
a equal to the value of
Here are some examples of Boolean expressions in action:
1 < 2 #>  TRUE 1 > 2 #>  FALSE 1 == 2 #>  FALSE value_1 <- 1 value_1 > 0 #>  TRUE value_2 <- value_1 + 10 value_1 + value_2 <= 12 #>  TRUE
6.4.2 Logical Operators
In practice, we often use two or more conditions to decide what to do. To combine different conditions, there are three logical operators:
& is similar to AND in English, that is,
x & y is true only if both
y are true. Second, is similar to OR in English, that is, A || B is false only if both
y are false. Third,
! is similar to NOT in English, that is,
!x is true only if
x is false.
x <- 10 y <- 20 # check to see if values are between 5 and 15 x > 5 & x < 15 #>  TRUE y > 5 & y < 15 #>  FALSE # more complex chains (x > 5 & x < 15) & (x > y & y < 15) #>  FALSE (x > 5 & x < 15) | (x > y & y < 15) #>  TRUE (x > 5 & x < 15) & !(x > y & y < 15) #>  TRUE
Different operator take different precendence. It is always a good practice to use brackets to control operation ordering.
6.4.3 Boolean Vectors
The nice thing about R is that you can use these comparison operators also on vectors. As with many expressions in R, the Boolean expressions discussed above are all vectorized. We'll learn more about vectors and vectorization later in this class, but here's a quick example:
x <- c(2.1, 4.2, 3.3, 5.4) x > 3 #>  FALSE TRUE TRUE TRUE
This command tests for every element of the vector if the condition stated by the comparison operator is
6.4.4 Boolean Vectors in Action
Boolean vectors are partially what makes R so magical. Check out the example below and examine each line. We'll cover subsetting operations later, but pay attention to the work of boolean expressions and logical operators.
# An example x <- c(1:10) x[(x>8) | (x<5)] #>  1 2 3 4 9 10 # How it works x <- c(1:10) x #>  1 2 3 4 5 6 7 8 9 10 x > 8 #>  FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE TRUE TRUE x < 5 #>  TRUE TRUE TRUE TRUE FALSE FALSE FALSE FALSE FALSE FALSE x > 8 | x < 5 #>  TRUE TRUE TRUE TRUE FALSE FALSE FALSE FALSE TRUE TRUE x[c(T,T,T,T,F,F,F,F,T,T)] #>  1 2 3 4 9 10
In the partially written code below,
vector_2 each contain 10 values. Using the fact that Boolean expressions are vectorized, write code that outputs:
- a vector of length 10 such that element
iof this vector equals
vector_1[i]is less than
- the number of times that element
vector_1is less than element
vector_2, using the
vector_1 <- c(1, 2, 4, 5, 3, 7, 8, 7, 1, 2) vector_2 <- c(1, 3, 4, 4, 5, 10, 6, 8, 9, 1) # YOUR CODE HERE
Technically, objects and variables are different things, but we will use the two interchangeably for now.↩