From 659883dff4fb02642295bb71f35285d2b812c426 Mon Sep 17 00:00:00 2001 From: colinleach Date: Tue, 18 Jul 2023 11:08:39 -0700 Subject: [PATCH 1/2] lists concept --- concepts/lists/.meta/config.json | 5 + concepts/lists/about.md | 152 +++++++++++++++++++++++++++++++ concepts/lists/introduction.md | 111 ++++++++++++++++++++++ concepts/lists/links.json | 6 ++ config.json | 5 + 5 files changed, 279 insertions(+) create mode 100644 concepts/lists/.meta/config.json create mode 100644 concepts/lists/about.md create mode 100644 concepts/lists/introduction.md create mode 100644 concepts/lists/links.json diff --git a/concepts/lists/.meta/config.json b/concepts/lists/.meta/config.json new file mode 100644 index 00000000..895d59b7 --- /dev/null +++ b/concepts/lists/.meta/config.json @@ -0,0 +1,5 @@ +{ + "authors": ["colinleach"], + "contributors": [], + "blurb": "A list in R is a collection that can hold heterogeneous data, including other lists." +} \ No newline at end of file diff --git a/concepts/lists/about.md b/concepts/lists/about.md new file mode 100644 index 00000000..c15ff560 --- /dev/null +++ b/concepts/lists/about.md @@ -0,0 +1,152 @@ +# About + +A `list` in R is an ordered collection of items, differing from `vectors` in a few ways: +- The items can be of different types (e.g. mixing `numeric` with `character`). +- The items can be complex structures (e.g. vectors, other lists, etc). +- There is some different syntax for accessing elements. + +Analogies to other languages are imprecise. +An R `list` is somewhat similar to a Python dictionary, but the `list` is ordered and can be accessed by numerical index. +It is somewhat similar to a C `struct`, except that the `list` can easily be extended at runtime. + +## Creating lists + +Giving names (often called "tags") to the elements is more common with lists than with vectors: + +```R +> list(x = 5.3, y = 4.2, color = "blue") +$x +[1] 5.3 + +$y +[1] 4.2 + +$color +[1] "blue" +``` + +However, tags are optional and R will then just use index numbers: + +```R +> list(5.3, 4.2, "blue") +[[1]] +[1] 5.3 + +[[2]] +[1] 4.2 + +[[3]] +[1] "blue" +``` + +## Accessing list elements + +There are three ways to do this, each useful in different contexts. + +### 1. With `$tag` notation + +Very common if the tag names are known in advance. + +```R +> point <- list(x = 5.3, y = 4.2, color = "blue") +> point$x +[1] 5.3 +> point$color +[1] "blue" +``` + +### 2. With `[[tag]]` notation + +This has the advantage that the tag name can be chosen at runtime. Note the double brackets. + +```R +> want <- "y" +> point[[want]] # same as point$y +[1] 4.2 +``` + +### 3. With position index + +This works whether or not the list has tags. Again, brackets are doubled. + +```R +> point[[3]] # same as point$color +[1] "blue" +``` + +## Adding and deleting elements + +Simple: assigning to an element will modify if it exists or add if it is new. + +```R +> point$color <- "red" +> point$trust <- TRUE +> str(point) # gives more compact output than the default display +List of 4 + $ x : num 5.3 + $ y : num 4.2 + $ color: chr "red" + $ trust: logi TRUE +``` + +To delete, assign `NULL` to the unwanted element. + +```R +> point$trust <- NULL +> str(point) +List of 3 + $ x : num 5.3 + $ y : num 4.2 + $ color: chr "red" +``` + +## Lists are "recursive vectors" + +The `vector` class is technically known as `atomic vector`, because it can only hold atomic values: `numeric`, `character`, `boolean`, etc. +Because a `list` can contain other lists, it is also known as a `recursive vector`. + +As well as being a technical point of nomenclature, this is a reminder that lists can have arbitrarily complex structure. +It is the programmer's responsibility to understand what will be provided when accessing a list element. + +## More on list indexing + +Some examples above used double brackets `[[ ]]` to access list emements. +This will try to flatten the element to its underlying type, useful if you just want a number or a string. + +Using single brackets `[ ]` will not do this flattening, and the returned value will be a sublist. + +```R +> point[["color"]] +[1] "red" # flattened + +> point["color"] +$color +[1] "red" # sublist +``` + +Even if the sublist is not what a novice R programmer is likely to want, be aware of it. +For maximum flexibility, many standard R functions return a `list`, even when it contains a single atomic value as here. + +To convert to a vector there are two possibilities. +- Take the first element with `[[1]]` +- Use the `unlist()` function. + +```R +> pt <-point["color"] + +> pt[[1]] +[1] "red" # simple 1-element vector + +> unlist(pt) +color +"red" # 1-element vector with name +``` + +Be careful with `unlist()`. Flattening the structure is useful in this case but can cause surprises with more complicated list elements. + + +## Advanced Topic: Internal Representation + +A `list`, like an atomic `vector`, is stored contiguously. The difference is that numeric and boolean vectors store *values*, but the list stores *references* to objects located elsewhere in memory. + +Knowing this is rarely important for an R user, but in a polyglot community like Exercism it may be helpful to programmers familiar with other languages. diff --git a/concepts/lists/introduction.md b/concepts/lists/introduction.md new file mode 100644 index 00000000..31950a90 --- /dev/null +++ b/concepts/lists/introduction.md @@ -0,0 +1,111 @@ +# Introduction + +A `list` in R is an ordered collection of items, differing from `vectors` in a few ways: +- The items can be of different types (e.g. mixing `numeric` with `character`). +- The items can be complex structures (e.g. vectors, other lists, etc). +- There is some different syntax for accessing elements. + +Analogies to other languages are imprecise. +An R `list` is somewhat similar to a Python dictionary, but the `list` is ordered and can be accessed by numerical index. +It is somewhat similar to a C `struct`, except that the `list` can easily be extended at runtime. + +## Creating lists + +Giving names (often called "tags") to the elements is more common with lists than with vectors: + +```R +> list(x = 5.3, y = 4.2, color = "blue") +$x +[1] 5.3 + +$y +[1] 4.2 + +$color +[1] "blue" +``` + +However, tags are optional and R will then just use index numbers: + +```R +> list(5.3, 4.2, "blue") +[[1]] +[1] 5.3 + +[[2]] +[1] 4.2 + +[[3]] +[1] "blue" +``` + +## Accessing list elements + +There are three ways to do this, each useful in different contexts. + +### 1. With `$tag` notation + +Very common if the tag names are known in advance. + +```R +> point <- list(x = 5.3, y = 4.2, color = "blue") +> point$x +[1] 5.3 +> point$color +[1] "blue" +``` + +### 2. With `[[tag]]` notation + +This has the advantage that the tag name can be chosen at runtime. Note the double brackets. + +```R +> want <- "y" +> point[[want]] # same as point$y +[1] 4.2 +``` + +### 3. With position index + +This works whether or not the list has tags. Again, brackets are doubled. + +```R +> point[[3]] # same as point$color +[1] "blue" +``` + +## Adding and deleting elements + +Simple: assigning to an element will modify if it exists or add if it is new. + +```R +> point$color <- "red" +> point$trust <- TRUE +> point +$x +[1] 5.3 + +$y +[1] 4.2 + +$color +[1] "red" + +$trust +[1] TRUE +``` + +To delete, assign `NULL` to the unwanted element. + +```R +> point$trust <- NULL +> point +$x +[1] 5.3 + +$y +[1] 4.2 + +$color +[1] "red" +``` diff --git a/concepts/lists/links.json b/concepts/lists/links.json new file mode 100644 index 00000000..088363ba --- /dev/null +++ b/concepts/lists/links.json @@ -0,0 +1,6 @@ +[ + { + "url": "https://intro2r.com/data-structures.html#lists", + "description": "Introduction to R: Lists" + } + ] \ No newline at end of file diff --git a/config.json b/config.json index b51aafcc..f7c08a38 100644 --- a/config.json +++ b/config.json @@ -586,6 +586,11 @@ "uuid": "2751b6f2-7d71-4397-b063-9bf927a57756", "slug": "booleans", "name": "Booleans" + }, + { + "uuid": "d2796a75-7571-4b3c-b926-60deae310f8f", + "slug": "lists", + "name": "Lists" } ], "key_features": [ From 0ac17622e7fc88a975e5d2c26cae2be20531bea9 Mon Sep 17 00:00:00 2001 From: colinleach Date: Tue, 18 Jul 2023 11:11:43 -0700 Subject: [PATCH 2/2] minor formatting --- concepts/lists/.meta/config.json | 2 +- concepts/lists/links.json | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/concepts/lists/.meta/config.json b/concepts/lists/.meta/config.json index 895d59b7..598ee2a8 100644 --- a/concepts/lists/.meta/config.json +++ b/concepts/lists/.meta/config.json @@ -2,4 +2,4 @@ "authors": ["colinleach"], "contributors": [], "blurb": "A list in R is a collection that can hold heterogeneous data, including other lists." -} \ No newline at end of file +} diff --git a/concepts/lists/links.json b/concepts/lists/links.json index 088363ba..e7532a30 100644 --- a/concepts/lists/links.json +++ b/concepts/lists/links.json @@ -1,6 +1,6 @@ [ - { - "url": "https://intro2r.com/data-structures.html#lists", - "description": "Introduction to R: Lists" - } - ] \ No newline at end of file + { + "url": "https://intro2r.com/data-structures.html#lists", + "description": "Introduction to R: Lists" + } +]