r_cookbook_basics

R Cookbook Chapter 2. Some Basics

Return to R Cookbook, R Bibliography, R DevOps, R Data Science, R Statistics, R Machine Learning, R Deep Learning, Data Science Bibliography, Statistics Bibliography

“ (RCook 2019)

“The R recipes in this chapter lie somewhere between R problem-solving ideas and R tutorials. Yes, they solve R common problems, but the R solutions showcase common R techniques and R idioms used in most R code, including the code in this R Cookbook]]. If you are new to R, we suggest skimming this chapter to acquaint yourself with these R idioms.” (RCook 2019)

2.1 Printing Something to the Screen

Problem: You want to display the R value of a R variable or R expression.

Solution: “If you simply enter the R variable name or R expression at the R command prompt, R will R print its value. Use the R print function for generic printing of any R object. Use the R cat function for producing R custom-formatted output.” (RCook 2019)

Discussion: It’s very easy to ask R to print something — just enter it at the R command prompt:

pi

  1. > [1] 3.14

R sqrt(2)

  1. > [1] 1.41

When you enter R expressions like these, R evaluates the R expression and then implicitly calls the R print function. So the previous example is identical to this:

R print(pi)

  1. > [1] 3.14

print(sqrt(2))

  1. > [1] 1.41

The beauty of R print is that it knows how to format any R value for printing, including structured values such as matrices and lists:

print(matrix(c(1, 2, 3, 4), 2, 2))

  1. > [,1] [,2]
  2. > [1,] 1 3
  3. > [2,] 2 4

print(list(“a”, “b”, “c”))

  1. > 1
  2. > [1] “a”
  3. >
  4. > 2
  5. > [1] “b”
  6. >
  7. > 3
  8. > [1] “c”

This is useful because you can always view your data: just print it. You need not write special printing logic, even for complicated data structures.

The print function has a significant limitation, however: it prints only one object at a time. Trying to print multiple items gives this mind-numbing error message:

print(“The zero occurs at”, 2 * pi, “radians.”)

  1. > Error in print.default(“The zero occurs at”, 2 * pi, “radians.”):
  2. > invalid 'quote' argument

The only way to print multiple items is to print them one at a time, which probably isn’t what you want:

print(“The zero occurs at”)

  1. > [1] “The zero occurs at”

print(2 * pi)

  1. > [1] 6.28

print(“radians”)

  1. > [1] “radians”

The cat function is an alternative to print that lets you concatenate multiple items into a continuous output:

cat(“The zero occurs at”, 2 * pi, “radians.”, “\n”)

  1. > The zero occurs at 6.28 radians.

Notice that cat puts a space between each item by default. You must provide a newline character (\n) to terminate the line.

The cat function can print simple vectors, too:

fib ← c(0, 1, 1, 2, 3, 5, 8, 13, 21, 34) cat(“The first few Fibonacci numbers are:”, fib, ”…\n“)

  1. > The first few Fibonacci numbers are: 0 1 1 2 3 5 8 13 21 34 …

Using cat gives you more control over your output, which makes it especially useful in R scripts that generate output consumed by others. A serious limitation, however, is that it cannot print compound data structures such as matrices and lists. Trying to cat them only produces another mind-numbing message:

cat(list(“a”, “b”, “c”))

  1. > Error in cat(list(“a”, “b”, “c”)): argument 1 (type 'list') cannot
  2. > be handled by 'cat'

See Also See Recipe 4.2 for controlling output format.

2.2 Setting Variables Problem You want to save a value in a variable.

Solution Use the assignment operator (←). There is no need to declare your variable first:

x ← 3 Discussion Using R in “calculator mode” gets old pretty fast. Soon you will want to define variables and save values in them. This reduces typing, saves time, and clarifies your work.

There is no need to declare or explicitly create variables in R. Just assign a value to the name and R will create the variable:

x ← 3 y ← 4 z ← sqrt(x^2 + y^2) print(z)

  1. > [1] 5

Notice that the assignment operator is formed from a less-than character (<) and a hyphen (-) with no space between them.

When you define a variable at the command prompt like this, the variable is held in your workspace. The workspace is held in the computer’s main memory but can be saved to disk. The variable definition remains in the workspace until you remove it.

R is a dynamically typed language, which means that we can change a variable’s data type at will. We could set x to be numeric, as just shown, and then turn around and immediately overwrite that with (say) a vector of character strings. R will not complain:

x ← 3 print(x)

  1. > [1] 3

x ← c(“fee”, “fie”, “foe”, “fum”) print(x)

  1. > [1] “fee” “fie” “foe” “fum”

In some R functions you will see assignment statements that use the strange-looking assignment operator «-:

x «- 3 That forces the assignment to a global variable rather than a local variable. Scoping is a bit, well, out of scope for this discussion, however.

In the spirit of full disclosure, we will reveal that R also supports two other forms of assignment statements. A single equals sign (=) can be used as an assignment operator. A rightward assignment operator (→) can be used anywhere the leftward assignment operator (←) can be used (but with the arguments reversed):

foo ← 3 print(foo)

  1. > [1] 3

5 → fum print(fum)

  1. > [1] 5

We recommend that you avoid these as well. The equals-sign assignment is easily confused with the test for equality. The rightward assignment can be useful in certain contexts, but it can be confusing to those not used to seeing it.

See Also See Recipes 2.4, 2.14, and 3.3. See also the help page for the assign function.

2.3 Listing Variables Problem You want to know what variables and functions are defined in your workspace.

Solution Use the ls function. Use ls.str for more details about each variable. You can also see your variables and functions in the Environment pane in RStudio, shown in the next recipe in Figure 2-1.

Discussion The ls function displays the names of objects in your workspace:

x ← 10 y ← 50 z ← c(“three”, “blind”, “mice”) f ← function(n, p) sqrt(p * (1 - p) / n) ls()

  1. > [1] “f” “x” “y” “z”

Notice that ls returns a vector of character strings in which each string is the name of one variable or function. When your workspace is empty, ls returns an empty vector, which produces this puzzling output:

ls()

  1. > character(0)

That is R’s quaint way of saying that ls returned a zero-length vector of strings; that is, it returned an empty vector because nothing is defined in your workspace.

If you want more than just a list of names, try ls.str; this will also tell you something about each variable:

x ← 10 y ← 50 z ← c(“three”, “blind”, “mice”) f ← function(n, p) sqrt(p * (1 - p) / n) ls.str()

  1. > f : function (n, p)
  2. > x : num 10
  3. > y : num 50
  4. > z : chr [1:3] “three” “blind” “mice”

The function is called ls.str because it is both listing your variables and applying the str function to them, showing their structure (see Recipe 12.13).

Ordinarily, ls does not return any name that begins with a dot (.). Such names are considered hidden and are not normally of interest to users. (This mirrors the Unix convention of not listing files whose names begin with a dot.) You can force ls to list everything by setting the all.names argument to TRUE:

ls()

  1. > [1] “f” “x” “y” “z”

ls(all.names = TRUE)

  1. > [1] ”.Random.seed“ “f” “x” “y”
  2. > [5] “z”

The Environment pane in RStudio also hides objects with names that begin with a dot.

See Also See Recipe 2.4 for deleting variables and Recipe 12.13 for inspecting your variables.

2.4 Deleting Variables Problem You want to remove unneeded variables or functions from your workspace or to erase its contents completely.

Solution Use the rm function.

Discussion Your workspace can get cluttered quickly. The rm function removes, permanently, one or more objects from the workspace:

x ← 2 * pi x

  1. > [1] 6.28

rm(x) x

  1. > Error in eval(expr, envir, enclos): object 'x' not found

There is no “undo”; once the variable is gone, it’s gone.

You can remove several variables at once:

rm(x, y, z) You can even erase your entire workspace at once. The rm function has a list argument consisting of a vector of names of variables to remove. Recall that the ls function returns a vector of variable names; hence, you can combine rm and ls to erase everything:

ls()

  1. > [1] “f” “x” “y” “z”

rm(list = ls()) ls()

  1. > character(0)

Alternatively, you could click the broom icon at the top of the Environment pane in RStudio, shown in Figure 2-1.

rcbk 0201 Figure 2-1. Environment pane in RStudio WARNING Never put rm(list=ls()) into code you share with others, such as a library function or sample code sent to a mailing list or Stack Overflow. Deleting all the variables in someone else’s workspace is worse than rude and will make you extremely unpopular.

See Also See Recipe 2.3.

2.5 Creating a Vector Problem You want to create a vector.

Solution Use the c(…) operator to construct a vector from given values.

Discussion Vectors are a central component of R, not just another data structure. A vector can contain either numbers, strings, or logical values, but not a mixture.

The c(…) operator can construct a vector from simple elements:

c(1, 1, 2, 3, 5, 8, 13, 21)

  1. > [1] 1 1 2 3 5 8 13 21

c(1 * pi, 2 * pi, 3 * pi, 4 * pi)

  1. > [1] 3.14 6.28 9.42 12.57

c(“My”, “twitter”, “handle”, “is”, ”@cmastication“)

  1. > [1] “My” “twitter” “handle” “is”
  2. > [5] ”@cmastication“

c(TRUE, TRUE, FALSE, TRUE)

  1. > [1] TRUE TRUE FALSE TRUE

If the arguments to c(…) are themselves vectors, it flattens them and combines them into one single vector:

v1 ← c(1, 2, 3) v2 ← c(4, 5, 6) c(v1, v2)

  1. > [1] 1 2 3 4 5 6

Vectors cannot contain a mix of data types, such as numbers and strings. If you create a vector from mixed elements, R will try to accommodate you by converting one of them:

v1 ← c(1, 2, 3) v3 ← c(“A”, “B”, “C”) c(v1, v3)

  1. > [1] “1” “2” “3” “A” “B” “C”

Here, we tried to create a vector from both numbers and strings. R converted all the numbers to strings before creating the vector, thereby making the data elements compatible. Note that R does this without warning or complaint.

Technically speaking, two data elements can coexist in a vector only if they have the same mode. The modes of 3.1415 and “foo” are numeric and character, respectively:

mode(3.1415)

  1. > [1] “numeric”

mode(“foo”)

  1. > [1] “character”

Those modes are incompatible. To make a vector from them, R converts 3.1415 to character mode so it will be compatible with “foo”:

c(3.1415, “foo”)

  1. > [1] “3.1415” “foo”

mode(c(3.1415, “foo”))

  1. > [1] “character”

WARNING c is a generic operator, which means that it works with many data types and not just vectors. However, it might not do exactly what you expect, so check its behavior before applying it to other data types and objects.

See Also See the introduction to Chapter 5 for more about vectors and other data structures.

2.6 Computing Basic Statistics Problem You want to calculate basic statistics: mean, median, standard deviation, variance, correlation, or covariance.

Solution Use one of these functions, assuming that x and y are vectors:

mean(x)

median(x)

sd(x)

var(x)

cor(x, y)

cov(x, y)

Discussion When you first use R you might open the documentation and begin searching for material entitled “Procedures for Calculating Standard Deviation.” It seems that such an important topic would likely require a whole chapter.

It’s not that complicated.

Standard deviation and other basic statistics are calculated by simple functions. Ordinarily, the function argument is a vector of numbers and the function returns the calculated statistic:

x ← c(0, 1, 1, 2, 3, 5, 8, 13, 21, 34) mean(x)

  1. > [1] 8.8

median(x)

  1. > [1] 4

sd(x)

  1. > [1] 11

var(x)

  1. > [1] 122

The sd function calculates the sample standard deviation, and var calculates the sample variance.

The cor and cov functions can calculate the correlation and covariance, respectively, between two vectors:

x ← c(0, 1, 1, 2, 3, 5, 8, 13, 21, 34) y ← log(x + 1) cor(x, y)

  1. > [1] 0.907

cov(x, y)

  1. > [1] 11.5

All these functions are picky about values that are not available (NA). Even one NA value in the vector argument causes any of these functions to return NA or even halt altogether with a cryptic error:

x ← c(0, 1, 1, 2, 3, NA) mean(x)

  1. > [1] NA

sd(x)

  1. > [1] NA

It’s annoying when R is that cautious, but it is appropriate. You must think carefully about your situation. Does an NA in your data invalidate the statistic? If yes, then R is doing the right thing. If not, you can override this behavior by setting na.rm=TRUE, which tells R to ignore the NA values:

x ← c(0, 1, 1, 2, 3, NA) sd(x, na.rm = TRUE)

  1. > [1] 1.14

In older versions of R, mean and sd were smart about data frames. They understood that each column of the data frame is a different variable, so they calculated their statistics for each column individually. This is no longer the case and, as a result, you may read confusing comments online or in older books (like the first edition of this book). In order to apply the functions to each column of a data frame we now need to use a helper function. The tidyverse family of helper functions for this sort of thing is in the purrr package. As with other tidyverse packages, this gets loaded when you run library(tidyverse). The function we’ll use to apply a function to each column of a data frame is map_dbl:

data(cars)

map_dbl(cars, mean)

  1. > speed dist
  2. > 15.4 43.0

map_dbl(cars, sd)

  1. > speed dist
  2. > 5.29 25.77

map_dbl(cars, median)

  1. > speed dist
  2. > 15 36

Notice in this example that mean and sd each return two values, one for each column defined by the data frame. (Technically, they return a two-element vector whose names attribute is taken from the columns of the data frame.)

The var function understands data frames without the help of a mapping function. It calculates the covariance between the columns of the data frame and returns the covariance matrix:

var(cars)

  1. > speed dist
  2. > speed 28 110
  3. > dist 110 664

Likewise, if x is either a data frame or a matrix, then cor(x) returns the correlation matrix and cov(x) returns the covariance matrix:

cor(cars)

  1. > speed dist
  2. > speed 1.000 0.807
  3. > dist 0.807 1.000

cov(cars)

  1. > speed dist
  2. > speed 28 110
  3. > dist 110 664

See Also See Recipe 2.14, Recipe 5.27, and Recipe 9.17.

2.7 Creating Sequences Problem You want to create a sequence of numbers.

Solution Use an n:m expression to create the simple sequence n, n+1, n+2, …, m:

1:5

  1. > [1] 1 2 3 4 5

Use the seq function for sequences with an increment other than 1:

seq(from = 1, to = 5, by = 2)

  1. > [1] 1 3 5

Use the rep function to create a series of repeated values:

rep(1, times = 5)

  1. > [1] 1 1 1 1 1

Discussion The colon operator (n:m) creates a vector containing the sequence n, n+1, n+2, …, m:

0:9

  1. > [1] 0 1 2 3 4 5 6 7 8 9

10:19

  1. > [1] 10 11 12 13 14 15 16 17 18 19

9:0

  1. > [1] 9 8 7 6 5 4 3 2 1 0

R was clever with the last expression (9:0). Because 9 is larger than 0, it counts backward from the starting to ending value. You can also use the colon operator directly with the pipe to pass data to another function:

10:20 %>% mean() The colon operator works for sequences that grow by 1 only. The seq function also builds sequences but supports an optional third argument, which is the increment:

seq(from = 0, to = 20)

  1. > [1] 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20

seq(from = 0, to = 20, by = 2)

  1. > [1] 0 2 4 6 8 10 12 14 16 18 20

seq(from = 0, to = 20, by = 5)

  1. > [1] 0 5 10 15 20

Alternatively, you can specify a length for the output sequence and then R will calculate the necessary increment:

seq(from = 0, to = 20, length.out = 5)

  1. > [1] 0 5 10 15 20

seq(from = 0, to = 100, length.out = 5)

  1. > [1] 0 25 50 75 100

The increment need not be an integer. R can create sequences with fractional increments, too:

seq(from = 1.0, to = 2.0, length.out = 5)

  1. > [1] 1.00 1.25 1.50 1.75 2.00

For the special case of a “sequence” that is simply a repeated value, you should use the rep function, which repeats its first argument:

rep(pi, times = 5)

  1. > [1] 3.14 3.14 3.14 3.14 3.14

See Also See Recipe 7.13 for creating a sequence of Date objects.

2.8 Comparing Vectors Problem You want to compare two vectors, or you want to compare an entire vector against a scalar.

Solution The comparison operators (==, !=, <, >, ⇐, >=) can perform an element-by-element comparison of two vectors. They can also compare a vector’s element against a scalar. The result is a vector of logical values in which each value is the result of one element-wise comparison.

Discussion R has two logical values, TRUE and FALSE. These are often called Boolean values in other programming languages.

The comparison operators compare two values and return TRUE or FALSE, depending upon the result of the comparison:

a ← 3 a == pi # Test for equality

  1. > [1] FALSE

a != pi # Test for inequality

  1. > [1] TRUE

a < pi

  1. > [1] TRUE

a > pi

  1. > [1] FALSE

a ⇐ pi

  1. > [1] TRUE

a >= pi

  1. > [1] FALSE

You can experience the power of R by comparing entire vectors at once. R will perform an element-by-element comparison and return a vector of logical values, one for each comparison:

v ← c(3, pi, 4) w ← c(pi, pi, pi) v == w # Compare two 3-element vectors

  1. > [1] FALSE TRUE FALSE

v != w

  1. > [1] TRUE FALSE TRUE

v < w

  1. > [1] TRUE FALSE FALSE

v ⇐ w

  1. > [1] TRUE TRUE FALSE

v > w

  1. > [1] FALSE FALSE TRUE

v >= w

  1. > [1] FALSE TRUE TRUE

You can also compare a vector against a single scalar, in which case R will expand the scalar to the vector’s length and then perform the element-wise comparison. The previous example can be simplified in this way:

v ← c(3, pi, 4) v == pi # Compare a 3-element vector against one number

  1. > [1] FALSE TRUE FALSE

v != pi

  1. > [1] TRUE FALSE TRUE

This is an application of the Recycling Rule discussed in Recipe 5.3.

After comparing two vectors, you often want to know whether any of the comparisons were true or whether all the comparisons were true. The any and all functions handle those tests. They both test a logical vector. The any function returns TRUE if any element of the vector is TRUE. The all function returns TRUE if all elements of the vector are TRUE:

v ← c(3, pi, 4) any(v == pi) # Return TRUE if any element of v equals pi

  1. > [1] TRUE

all(v == 0) # Return TRUE if all elements of v are zero

  1. > [1] FALSE

See Also See Recipe 2.9.

2.9 Selecting Vector Elements Problem You want to extract one or more elements from a vector.

Solution Select the indexing technique appropriate for your problem:

Use square brackets to select vector elements by their position, such as v[3] for the third element of v.

Use negative indexes to exclude elements.

Use a vector of indexes to select multiple values.

Use a logical vector to select elements based on a condition.

Use names to access named elements.

Discussion Selecting elements from vectors is another powerful feature of R. Basic selection is handled just as in many other programming languages—use square brackets and a simple index:

fib ← c(0, 1, 1, 2, 3, 5, 8, 13, 21, 34) fib

  1. > [1] 0 1 1 2 3 5 8 13 21 34

fib[1]

  1. > [1] 0

fib[2]

  1. > [1] 1

fib[3]

  1. > [1] 1

fib[4]

  1. > [1] 2

fib[5]

  1. > [1] 3

Notice that the first element has an index of 1, not 0 as in some other programming languages.

A cool feature of vector indexing is that you can select multiple elements at once. The index itself can be a vector, and each element of that indexing vector selects an element from the data vector:

fib[1:3] # Select elements 1 through 3

  1. > [1] 0 1 1

fib[4:9] # Select elements 4 through 9

  1. > [1] 2 3 5 8 13 21

An index of 1:3 means select elements 1, 2, and 3, as just shown. The indexing vector needn’t be a simple sequence, however. You can select elements anywhere within the data vector—as in this example, which selects elements 1, 2, 4, and 8:

fib[c(1, 2, 4, 8)]

  1. > [1] 0 1 2 13

R interprets negative indexes to mean exclude a value. An index of –1, for instance, means exclude the first value and return all other values:

fib[-1] # Ignore first element

  1. > [1] 1 1 2 3 5 8 13 21 34

You can extend this method to exclude whole slices by using an indexing vector of negative indexes:

fib[1:3] # As before

  1. > [1] 0 1 1

fib[-(1:3)] # Invert sign of index to exclude instead of select

  1. > [1] 2 3 5 8 13 21 34

Another indexing technique uses a logical vector to select elements from the data vector. Everywhere that the logical vector is TRUE, an element is selected:

fib < 10 # This vector is TRUE wherever fib is less than 10

  1. > [1] TRUE TRUE TRUE TRUE TRUE TRUE TRUE FALSE FALSE FALSE

fib[fib < 10] # Use that vector to select elements less than 10

  1. > [1] 0 1 1 2 3 5 8

fib 2 == 0 # This vector is TRUE wherever fib is even #> [1] TRUE FALSE FALSE TRUE FALSE FALSE TRUE FALSE FALSE TRUE fib[fib 2 == 0] # Use that vector to select the even elements

  1. > [1] 0 2 8 34

Ordinarily, the logical vector should be the same length as the data vector so you are clearly either including or excluding each element. (If the lengths differ, then you need to understand the Recycling Rule, discussed in Recipe 5.3.)

By combining vector comparisons, logical operators, and vector indexing, you can perform powerful selections with very little R code.

For example, you can select all elements greater than the median:

v ← c(3, 6, 1, 9, 11, 16, 0, 3, 1, 45, 2, 8, 9, 6, -4) v[ v > median(v)]

  1. > [1] 9 11 16 45 8 9

or select all elements in the lower and upper 5%:

v[ (v < quantile(v, 0.05)) ]] | > [1] 45 -4 The previous example uses the | > [1] 45 -4 or select all elements that are neither NA nor NULL: v <- c(1, 2, 3, NA, 5) v[!is.na(v) & !is.null(v)] #> [1] 1 2 3 5 One final indexing feature lets you select elements by name. It assumes that the vector has a names attribute, defining a name for each element. You can define the names by assigning a vector of character strings to the attribute: years <- c(1960, 1964, 1976, 1994) names(years) <- c("Kennedy", "Johnson", "Carter", "Clinton") years #> Kennedy Johnson Carter Clinton #> 1960 1964 1976 1994 Once the names are defined, you can refer to individual elements by name: years["Carter"] #> Carter #> 1976 years["Clinton"] #> Clinton #> 1994 This generalizes to allow indexing by vectors of names; R returns every element named in the index: years[c("Carter", "Clinton")] #> Carter Clinton #> 1976 1994 See Also See Recipe 5.3 for more about the Recycling Rule. 2.10 Performing Vector Arithmetic Problem You want to operate on an entire vector at once. Solution The usual arithmetic operators can perform element-wise operations on entire vectors. Many functions operate on entire vectors, too, and return a vector result. Discussion Vector operations are one of R’s great strengths. All the basic arithmetic operators can be applied to pairs of vectors. They operate in an element-wise manner; that is, the operator is applied to corresponding elements from both vectors: v <- c(11, 12, 13, 14, 15) w <- c(1, 2, 3, 4, 5) v + w #> [1] 12 14 16 18 20 v - w #> [1] 10 10 10 10 10 v * w #> [1] 11 24 39 56 75 v / w #> [1] 11.00 6.00 4.33 3.50 3.00 w^v #> [1] 1.00e+00 4.10e+03 1.59e+06 2.68e+08 3.05e+10 Observe that the length of the result here is equal to the length of the original vectors. The reason is that each element comes from a pair of corresponding values in the input vectors. If one operand is a vector and the other is a scalar, then the operation is performed between every vector element and the scalar: w #> [1] 1 2 3 4 5 w + 2 #> [1] 3 4 5 6 7 w - 2 #> [1] -1 0 1 2 3 w * 2 #> [1] 2 4 6 8 10 w / 2 #> [1] 0.5 1.0 1.5 2.0 2.5 2^w #> [1] 2 4 8 16 32 For example, you can recenter an entire vector in one expression simply by subtracting the mean of its contents: w #> [1] 1 2 3 4 5 mean(w) #> [1] 3 w - mean(w) #> [1] -2 -1 0 1 2 Likewise, you can calculate the z-score of a vector in one expression—subtract the mean and divide by the standard deviation: w #> [1] 1 2 3 4 5 sd(w) #> [1] 1.58 (w - mean(w)) / sd(w) #> [1] -1.265 -0.632 0.000 0.632 1.265 Yet the implementation of vector-level operations goes far beyond elementary arithmetic. It pervades the language, and many functions operate on entire vectors. The functions sqrt and log, for example, apply themselves to every element of a vector and return a vector of results: w <- 1:5 w #> [1] 1 2 3 4 5 sqrt(w) #> [1] 1.00 1.41 1.73 2.00 2.24 log(w) #> [1] 0.000 0.693 1.099 1.386 1.609 sin(w) #> [1] 0.841 0.909 0.141 -0.757 -0.959 There are two great advantages to vector operations. The first and most obvious is convenience. Operations that require looping in other languages are one-liners in R. The second is speed. Most vectorized operations are implemented directly in C code, so they are substantially faster than the equivalent R code you could write. See Also Performing an operation between a vector and a scalar is actually a special case of the Recycling Rule; see Recipe 5.3. 2.11 Getting Operator Precedence Right Problem Your R expression is producing a curious result, and you wonder if operator precedence is causing problems. Solution The full list of operators is shown in Table 2-1, listed in order of precedence from highest to lowest. Operators of equal precedence are evaluated from left to right except where indicated. Table 2-1. Operator precedence Operator Meaning See also [ [[ Indexing Recipe 2.9 :: ::: Access variables in a namespace (environment) $ @ Component extraction, slot extraction ^ Exponentiation (right to left) - + Unary minus and plus : Sequence creation Recipe 2.7, Recipe 7.13 %any% (including %>%) Special operators Discussion (this recipe) * / Multiplication, division Discussion (this recipe) + - Addition, subtraction == != < > <= >= Comparison Recipe 2.8 ! Logical negation & && Logical “and,” short-circuit “and” | r_cookbook_basics | r_cookbook_basics | Logical “or,” short-circuit “or” ~ Formula Recipe 11.1 -> ->> Rightward assignment Recipe 2.2 = Assignment (right to left) Recipe 2.2 <- <<- Assignment (right to left) Recipe 2.2 or vice versa If the variable lst contains a list, it can be indexed in two ways: lstn is the nth element of the list, whereas lst[n] is a list whose only element is the nth element of lst. That’s a big difference. See Recipe 5.7.

Using & instead of &&, or vice versa; same for ]] | and | r_cookbook_basics | Use & and | in logical expressions involving the logical values TRUE and FALSE. See Recipe 2.9. Use && and | r_cookbook_basics | for the flow-of-control expressions inside if and while statements. Programmers accustomed to other programming languages may reflexively use && and | r_cookbook_basics | everywhere because “they are faster.” But those operators give peculiar results when applied to vectors of logical values, so avoid them unless you are sure that they do what you want. Passing multiple arguments to a single-argument function What do you think is the value of mean(9,10,11) Sources:


Cloud Monk is Retired ( for now). Buddha with you. © 2025 and Beginningless Time - Present Moment - Three Times: The Buddhas or Fair Use. Disclaimers

SYI LU SENG E MU CHYWE YE. NAN. WEI LA YE. WEI LA YE. SA WA HE.


r_cookbook_basics.txt · Last modified: 2025/02/01 06:33 by 127.0.0.1

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki