The Big R-Book. Philippe J. S. De Brouwer
which defines the number of dimension. While arrays are similar to lists, they have to be of one class type (lists can consist of different class types).
array()
In the example we create an array with two elements, which are both three by three matrices.
# Create an array: a <- array(c(‘A’,‘B’),dim = c(3,3,2)) print(a) ## , , 1 ## ## [,1] [,2] [,3] ## [1,] "A" "B" "A" ## [2,] "B" "A" "B" ## [3,] "A" "B" "A" ## ## , , 2 ## ## [,1] [,2] [,3] ## [1,] "B" "A" "B" ## [2,] "A" "B" "A" ## [3,] "B" "A" "B" # Access one element: a[2,2,2] ## [1] "B" # Access one layer: a[,,2] ## [,1] [,2] [,3] ## [1,] "B" "A" "B" ## [2,] "A" "B" "A" ## [3,] "B" "A" "B"
4.3.5.2 Naming Elements of Arrays
In most applications it will be enough, to refer to an element in an array by its number. However naming elements makes code easier to read and can make it more robust. For example, if we change the array definition, the numbers of its elements can change, but the name will still be a valid reference.
# Create two vectors: v1 <- c(1,1) v2 <- c(10:13) col.names <- c("col1","col2", "col3") row.names <- c("R1","R2") matrix.names <- c("Matrix1","Matrix2") # Take these vectors as input to the array. a <- array(c(v1,v2),dim = c(2,3,2), dimnames = list(row.names,col.names, matrix.names)) print(a) # This allows to address the first row in Matrix 1 as follows: a[‘R1’,,‘Matrix1’]
4.3.5.3 Manipulating Arrays
Using arrays and accessing its elements is in many aspects similar to working with matrices.
M1 <- a[,,1] M2 <- a[,,2] M2 ## col1 col2 col3 ## R1 1 10 12 ## R2 1 11 13
4.3.5.4 Applying Functions over Arrays
While it is possible to use a for-loop and cycle through the elements of an array, it is usually faster to use the built-in functions that R provides.
An efficient way to apply the same function over each element of an array is via the function apply()
: that functions is designed to do exactly that.
apply()
Function use for apply()
apply(X, MARGIN, FUN, …) with:
1 X: an array, including a matrix.
2 MARGIN: a vector giving the subscripts which the function will be applied over. E.g., for a matrix ‘1’ indicates rows, ‘2’ indicates columns, ‘c(1, 2)’ indicates rows and columns. Where ‘X’ has named dimnames, it can be a character vector selecting dimension names.
3 FUN: the function to be applied: see ‘Details’. In the case of functions like ‘+’, ‘backquoted or quoted
It is sufficient to provide the data, the dimension of application and the function that has to be applied. To show how this works, we construct a simple example to calculate sums of rows and sums of columns.
cbind()
x <- cbind(x1 = 3, x2 = c(4:1, 2:5)) dimnames(x)[[1]] <- letters[1:8] apply(x, 2, mean, trim = .2) ## x1 x2 ## 3 3 col.sums <- apply(x, 2, sum) row.sums <- apply(x, 1, sum) rbind(cbind(x, Rtot = row.sums), Ctot = c(col.sums, sum(col.sums))) ## x1 x2 Rtot ## a 3 4 7 ## b 3 3 6 ## c 3 2 5 ## d 3 1 4 ## e 3 2 5 ## f 3 3 6 ## g 3 4 7 ## h 3 5 8 ## Ctot 24 24 48
The reader will notice that in the example above the variable x
is actually not an array but rather a data frame. The function apply()
works however the same: instead of 2 dimensions, there can be more.
apply()
Consider the previous example with the array a
, and remember that a
has three dimensions: 2 rows, 3 columns, and 2 matrices, then the following should be clear.
# Re-create the array a (shorter code): col.names <- c("col1","col2", "col3") row.names <- c(“R1”,“R2”) matrix.names <- c(“Matrix1”,“Matrix2”) a <- array(c(1,1,10:13),dim = c(2,3,2), dimnames = list(row.names,col.names, matrix.names)) # Demonstrate apply: apply(a, 1, sum) ## R1 R2 ## 46 50 apply(a, 2, sum) ## col1 col2 col3 ## 4 42 50 apply(a, 3, sum) ## Matrix1 Matrix2 ## 48 48
4.3.6 Lists
Where vectors, arrays, and matrices only can contain variables of the same sort (numeric, character, integer, etc.), the list object allows to mix different types into one object. The concept of a list is similar to the concept “object” in many programming languages such as C++. Notice, however, that there is no abstraction, only instances.
list
4.3.6.1 Creating Lists
list()
Definition: List
In R, lists are objects which are sets of elements that are not necessarily all of the same type. Lists can mix numbers, strings, vectors, matrices, functions, boolean variables, and even lists.
# List is created using list() function. myList <- list(“Approximation”, pi, 3.14, c) print(myList) ## [[1]] ## [1] “Approximation” ## ## [[2]] ## [1] 3.141593 ## ## [[3]] ## [1] 3.14 ## ## [[4]] ## function (…) .Primitive(“c”)
List might be reminiscent to how objects work in other languages (e.g. it looks similar to the struct
in C). Indeed, everything is an object in R. However, to understand how R implements different styles of objects and object-oriented programming, we recommend to read Chapter 6 on page 117.
4.3.6.2 Naming Elements of Lists
While it is perfectly possible to address elements of lists by their number, it is sometimes more meaningful to use a specific name.
# Create the list: L <- list(“Approximation”, pi, 3.14, c) # Assign names to elements: names(L) <- c(“description”, “exact”, “approx”,“function”) print(L) ## $description ## [1] “Approximation” ## ## $exact ## [1] 3.141593 ## ## $approx ## [1] 3.14 ## ## $`function` ## function (…) .Primitive(“c”) # Addressing elements of the named list: print(paste(“The difference is”, L$exact - L$approx)) ## [1] “The difference is 0.00159265358979299” print(L[3]) ## $approx ## [1] 3.14 print(L$approx) ## [1] 3.14 # However, “function” was a reserved word, so we need