The Big R-Book. Philippe J. S. De Brouwer
Чтение книги онлайн.
Читать онлайн книгу The Big R-Book - Philippe J. S. De Brouwer страница 30

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 to use # back-ticks in order to address the element: a <- L$`function`(2,3,pi,5) # to access the function c(…) print(a) ## [1] 2.000000 3.000000 3.141593 5.000000
4.3.6.3 List Manipulations
Since lists can contain objects of different types, it would have been confusing to overload the base operators such as the addition. There are a few other things that make sense.
Lists of Lists Are Also Lists
V1 <- c(1,2,3) L2 <- list(V1, c(2:7)) L3 <- list(L2,V1) print(L3) ## [[1]] ## [[1]][[1]] ## [1] 1 2 3 ## ## [[1]][[2]] ## [1] 2 3 4 5 6 7 ## ## ## [[2]] ## [1] 1 2 3 print(L3[[1]][[2]][3]) ## [1] 4
Note how the list L3
is a list of lists, rather than the concatenation of two lists. Instead of adding the elements of L2 after those of V1 and having nine slots for data, it has two slots. Each of those slots contains the object V1
and L2
respectively.
The double square brackets will inform R that we want one element returned as the most elementary class and is limited to returning one position. The simple square brackets will return a list and can be given a range.
# The first object of L2 as a list: L2[1] ## [[1]] ## [1] 1 2 3 class(L[2]) ## [1] “list” # The first element of L2 is a numeric vector: L2[[1]] ## [1] 1 2 3 class(L2[[2]]) ## [1] “integer” # range L2[1:2] ## [[1]] ## [1] 1 2 3 ## ## [[2]] ## [1] 2 3 4 5 6 7 # Unexpected result (ranges are not to be used with x[[.]]): L2[[1:2]] <- ‘a’ L2 ## [[1]] ## [1] “1” “a” “3” ## ## [[2]] ## [1] 2 3 4 5 6 7 # Is this what you would expect? L2[1:2] <- ‘a’ L2 ## [[1]] ## [1] “a” ## ## [[2]] ## [1] “a”
Add and Delete Elements of a List
A numbered element can be added while skipping positions. In the following example the position 3 is left undefined (NULL).
L <- list(1,2) L[4] <- 4 # position 3 is NULL L ## [[1]] ## [1] 1 ## ## [[2]] ## [1] 2 ## ## [[3]] ## NULL ## ## [[4]] ## [1] 4
Named elements are always added at the end of the list:
L$pi_value <- pi L ## [[1]] ## [1] 1 ## ## [[2]] ## [1] 2 ## ## [[3]] ## NULL ## ## [[4]] ## [1] 4 ## ## $pi_value ## [1] 3.141593
Delete an element by assigning NULL to it:
L[1] <- NULL L ## [[1]] ## [1] 2 ## ## [[2]] ## NULL ## ## [[3]] ## [1] 4 ## ## $pi_value ## [1] 3.141593
It is also possible to delete an element via the squared brackets. Note that if we address the elements of a list by their number, we need to recalculate the numbers. If we were addressing the elements of the list by name, nothing needs to be changed.
L <- L[-2] L ## [[1]] ## [1] 2 ## ## [[2]] ## [1] 4 ## ## $pi_value ## [1] 3.141593
When deleting an element in a list, the numbering will change so that it appears that the deleted element was never there. This implies that when accessing elements of the list by number, it is unsafe to delete elements and can lead to unwanted side effects of the code.
Convert list to vectors
Vectors can only contain one type of variable, while a list can be of mixed types. It might make sense to convert lists to vectors, for example, because some operations on vectors will be significantly faster.
unlist()
To do this R, provides the function unlist()
.
L <- list(c(1:5), c(6:10)) v1 <- unlist(L[1]) v2 <- unlist(L[2]) v2-v1 ## [1] 5 5 5 5 5
Lists are more complex than vectors, instead of failing with a warning and requiring additional options to be set, the unlist()
function will silentlymake some decisions for you.
# A list of vectors of integers: L <- list(1L,c(-10L:-8L)) unlist(L) ## [1] 1 -10 -9 -8 # Note