############################################################################.
# Intro to Modifying lists - a word of caution ...
############################################################################.
# Replacing, removing and adding items to a list all can be done
# with assignment statements. When using assignment statements to
# modify lists, you must pay careful attention to what is on the
# the left hand side (LHS) of the = sign in the assignment
# statement and what is on the right hand side (RHS) of the = sign.
#
# The LHS of the assignment always contains a list. However, the list
# on the LHS might use [single-brackets] or [[double-brackets]].
# It's very important to pay attention to the difference as they
# have different effects.
#
# The value on the RHS might be another list or a vector. Again, it's
# very important to pay attention to the mode of the data on the RHS.
# The result will be very different if the RHS contains a list vs if the
# RHS contains a vector.
#
# It's easier to understand all this when you see examples.
# I think it's easier to understand when you use [[double-brackets]]
# on the LHS, so we'll start with that ...
############################################################################.
26 24. Modifying Lists: (1) removing items (2) adding items (3) replacing items
26.1 Removing objects from a list with NULL
#---------------------------------------------------------------.
# Removing objects from a list with NULL
#---------------------------------------------------------------.
# NULL is a "special value" that can be understood as "nothing".
# To remove an item from a list, you can assign NULL to that value.
#
# We'll discuss this in more depth below. For now, let's just see an example:
#---------------------------------------------------------------.
# let's recreate all of the data
rm(list= ls())
= list(c("bob", "charlie", "frank"),
gradebook c(70,80,90),
c(75,85,88),
c(TRUE, FALSE,FALSE))
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~.
# You can use [single-brackets]
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~.
3] = NULL # remove the third item from the gradebook
gradebook[
str(gradebook) # the 3rd value is removed
List of 3
$ : chr [1:3] "bob" "charlie" "frank"
$ : num [1:3] 70 80 90
$ : logi [1:3] TRUE FALSE FALSE
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~.
# You can also use [[double-brackets]]
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~.
2]] = NULL # removes the 2nd item from the list
gradebook[[str(gradebook) # the 2nd value is removed
List of 2
$ : chr [1:3] "bob" "charlie" "frank"
$ : logi [1:3] TRUE FALSE FALSE
You cannot use NULL to remove values from vectors.
#------------------------------------------------------------------.
# VECTORS and LISTS are fundamentally different in how they
# work "under the covers". As a result, you
# cannot use NULL to remove values from vectors.
#------------------------------------------------------------------.
= c(100,200,300,400)
nums nums
[1] 100 200 300 400
3] = NULL # This doesn't work nums[
Error in nums[3] = NULL: replacement has length zero
# nothing happened to nums nums
[1] 100 200 300 400
Removing more than one item in one command with [single-brackets]
rm(list=ls()) # Let's start from scratch
= list(c("bob", "charlie", "frank"),
gradebook c(70,80,90),
c(75,85,88),
c(TRUE, FALSE,FALSE))
str(gradebook)
List of 4
$ : chr [1:3] "bob" "charlie" "frank"
$ : num [1:3] 70 80 90
$ : num [1:3] 75 85 88
$ : logi [1:3] TRUE FALSE FALSE
# To remove more than one item from the list at once, use [single-brackets]
# and use more than one value in the index.
c(1,2)] = NULL
gradebook[str(gradebook)
List of 2
$ : num [1:3] 75 85 88
$ : logi [1:3] TRUE FALSE FALSE
# You cannot use [[double-brackets]] for this ...
# That makes sense since this would actually try to use recursive
# indexing to set the 2nd value in the 1st vector to NULL. However,
# you cannot set values in vectors to NULL.
#
c(1,2)]] = NULL # ERROR gradebook[[
Error in gradebook[[c(1, 2)]] = NULL: replacement has length zero
str(gradebook)
List of 2
$ : num [1:3] 75 85 88
$ : logi [1:3] TRUE FALSE FALSE
26.2 Adding items to a list - 3 different ways
##############################################################################.
# There are 3 different way to add items to a list
#
# option 1 - Use the c() function.
#
# option 2 - Use the append() function.
#
# option 3 - Assign new items to positions past the end of the list.
# Pay careful attention to using [single-brackets] vs [[double-brackets]]
#
# See the examples below ...
##############################################################################.
add to a list - option 1 - use the c() function
rm(list=ls()) # start from scratch
= list(c("bob", "charlie", "frank"),
gradebook c(70,80,90),
c(75,85,88),
c(TRUE, FALSE,FALSE))
#######################################################################.
# Adding to a list - option #1 - use the c() function
#---------------------------------------------------------------------.
# The c() function can be used to combines lists in the same way it
# can be used to combine vectors.
# c(list1, list2, list3) # a new combined list of all the items
# See the example.
#######################################################################.
# Create a LIST that contains the new data
= list(c(61, 62, 63, 64), # another test
newData c("senior", "sophomore", "senior", "freshman") # year in school
)
# combine the lists with the c function
= c(gradebook, newData)
combinedList str(combinedList)
List of 6
$ : chr [1:3] "bob" "charlie" "frank"
$ : num [1:3] 70 80 90
$ : num [1:3] 75 85 88
$ : logi [1:3] TRUE FALSE FALSE
$ : num [1:4] 61 62 63 64
$ : chr [1:4] "senior" "sophomore" "senior" "freshman"
add to a list - option 2 - use the append() function
rm(list=ls()) # start from scratch
= list(c("bob", "charlie", "frank"),
gradebook c(70,80,90),
c(75,85,88),
c(TRUE, FALSE,FALSE))
#######################################################################.
# Adding to a list - option #2 - use the append() function
#
# Append the values in a one list onto the end of another list.
# see examples below
#######################################################################.
# Create a LIST that contains the new data
= list(c(61, 62, 63, 64), # another test
newData c("senior", "sophomore", "senior", "freshman") # year in school
)
# combine the lists with the append function
= append(gradebook, newData)
combinedList str(combinedList)
List of 6
$ : chr [1:3] "bob" "charlie" "frank"
$ : num [1:3] 70 80 90
$ : num [1:3] 75 85 88
$ : logi [1:3] TRUE FALSE FALSE
$ : num [1:4] 61 62 63 64
$ : chr [1:4] "senior" "sophomore" "senior" "freshman"
# NOTE - the append function works with vectors too.
# It can be used in other ways as well.
# For more info see the help page.
# ?append
add to a list - option 3 - assign new items to positions past the end of the list
rm(list=ls()) # start from scratch
= list(c("bob", "charlie", "frank"),
gradebook c(70,80,90),
c(75,85,88),
c(TRUE, FALSE,FALSE))
# If you add an item using [[double-brackets]]
# Whatever is on the RHS will be placed in the one position
# identified on the LHS.
5]] = c("senior", "senior", "junior")
gradebook[[
gradebook
[[1]]
[1] "bob" "charlie" "frank"
[[2]]
[1] 70 80 90
[[3]]
[1] 75 85 88
[[4]]
[1] TRUE FALSE FALSE
[[5]]
[1] "senior" "senior" "junior"
# If you add an item using [single-brackets] the values in the list (or vector)
# on the RHS will be assigned to the corresponding positions on the LHS.
#
# The following has a list of two values on the RHS.
# The 1st vector in the list on the RHS is assigned to position 6
# The 2nd vector in the list on the RHS is assigned to position 7
c(6,7)] = list(c("B.", "David", "Loyd"), # middle names
gradebook[c("Berger", "Chaplan", "Wright") # last names
) gradebook
[[1]]
[1] "bob" "charlie" "frank"
[[2]]
[1] 70 80 90
[[3]]
[1] 75 85 88
[[4]]
[1] TRUE FALSE FALSE
[[5]]
[1] "senior" "senior" "junior"
[[6]]
[1] "B." "David" "Loyd"
[[7]]
[1] "Berger" "Chaplan" "Wright"
You can reorganize items in the list after you add the new items.
# We added middle and last names to the end of the list.
# However, it would be nice if they were at the beginning of the list.
# We can reorganize the list.
# This is the way the list looks as of now. Notice that the middle
# and last names are in the 6th and 7th positions in the list.
gradebook
[[1]]
[1] "bob" "charlie" "frank"
[[2]]
[1] 70 80 90
[[3]]
[1] 75 85 88
[[4]]
[1] TRUE FALSE FALSE
[[5]]
[1] "senior" "senior" "junior"
[[6]]
[1] "B." "David" "Loyd"
[[7]]
[1] "Berger" "Chaplan" "Wright"
# Let's rearrange the list so the first,middle and last names are
# all at the beginning of the list.
= gradebook[c(1,6,7,2:5)]
gradebook
# Here is the new list
gradebook
[[1]]
[1] "bob" "charlie" "frank"
[[2]]
[1] "B." "David" "Loyd"
[[3]]
[1] "Berger" "Chaplan" "Wright"
[[4]]
[1] 70 80 90
[[5]]
[1] 75 85 88
[[6]]
[1] TRUE FALSE FALSE
[[7]]
[1] "senior" "senior" "junior"
Skipped entries in a list contain NULL
# If you skip entires in a list then the missing entries are NULL.
# You probably wouldn't want to do that. However, it's good
# to understand what's happening if you do do it.
rm(list=ls()) # start from scratch
= list(c("bob", "charlie", "frank"),
gradebook c(70,80,90),
c(75,85,88),
c(TRUE, FALSE,FALSE))
# Assign a new value to position 7
7]] = c("some","new","values")
gradebook[[
# Positions 5 and 6 will "implicitly" contain NULL
# (i.e. we didn't actually assign NULL)
gradebook
[[1]]
[1] "bob" "charlie" "frank"
[[2]]
[1] 70 80 90
[[3]]
[1] 75 85 88
[[4]]
[1] TRUE FALSE FALSE
[[5]]
NULL
[[6]]
NULL
[[7]]
[1] "some" "new" "values"
# If we want to remove those positions we can
# EXPLICITLY assign NULL to those positions.
# (Sounds strange, but this will actually work.)
c(5,6)] = NULL
gradebook[
gradebook
[[1]]
[1] "bob" "charlie" "frank"
[[2]]
[1] 70 80 90
[[3]]
[1] 75 85 88
[[4]]
[1] TRUE FALSE FALSE
[[5]]
[1] "some" "new" "values"
You can add items to an empty list (this will be a useful technique later)
#############################################################################.
# Add items to an empty list (this will be a useful technique later)
#############################################################################.
= list() # this creates an empty list
stuff stuff
list()
str(stuff)
list()
# add a value to the 1st position
1]] = c("apple", "pear", "banana")
stuff[[
# add a value to the 2nd position
2]] = c("red", "green", "yellow")
stuff[[
# add values to the 3rd and 4th positions using [single-brackets]
c(3,4)] = list( c(1.99, 2.99, 3.99), # price
stuff[c(TRUE, FALSE, TRUE)) # on sale
# Here is the new data
str(stuff)
List of 4
$ : chr [1:3] "apple" "pear" "banana"
$ : chr [1:3] "red" "green" "yellow"
$ : num [1:3] 1.99 2.99 3.99
$ : logi [1:3] TRUE FALSE TRUE
# You can also add an entire list
# (gradebook was defined above - this should probably be a better example)
5]] = gradebook
stuff[[str(stuff)
List of 5
$ : chr [1:3] "apple" "pear" "banana"
$ : chr [1:3] "red" "green" "yellow"
$ : num [1:3] 1.99 2.99 3.99
$ : logi [1:3] TRUE FALSE TRUE
$ :List of 5
..$ : chr [1:3] "bob" "charlie" "frank"
..$ : num [1:3] 70 80 90
..$ : num [1:3] 75 85 88
..$ : logi [1:3] TRUE FALSE FALSE
..$ : chr [1:3] "some" "new" "values"
26.3 Replacing items in a list
Using [[double-brackets]] to replace entries in a list
#####################################################################.
# Using [[double-brackets]] to replace entries in a list
#
# SOME_LIST[[ 1 ]] = SOME_VALUE
#
# The value at the specified position is replaced with SOME_VALUE
#####################################################################.
rm(list=ls()) # start from scratch
= list( c("bob", "charlie", "frank"), # student names
gradebook c(70,80,90), # grades from first test
c(75,85,88), # grades from second test
c(TRUE, FALSE,FALSE)) # TRUE for honors students
#---------------------------------------------------------------------------.
# Remember that SOME_LIST[[double-brackets]] will identify EXACTLY ONE item.
#
# If you use [[double-brackets]] on the LHS of the = sign then whatever
# is on the RHS of the = sign will replace the one item that is
# identified on the LHS of the = sign.
#---------------------------------------------------------------------------.
# EXAMPLE:
# Replace the 1st item in the list with new vector of names
1]] = c("anne", "betty", "carla")
gradebook[[ gradebook
[[1]]
[1] "anne" "betty" "carla"
[[2]]
[1] 70 80 90
[[3]]
[1] 75 85 88
[[4]]
[1] TRUE FALSE FALSE
— Practice —
#########################################################################.
# QUESTION - write code to replace the 2nd item in the list with a new
# vector that adds 1 point to each grade.
#########################################################################.
# Answer
2]] = gradebook[[2]] + 1
gradebook[[ gradebook
[[1]]
[1] "anne" "betty" "carla"
[[2]]
[1] 71 81 91
[[3]]
[1] 75 85 88
[[4]]
[1] TRUE FALSE FALSE
Another example - insert a list into a list
rm(list=ls()) # start from scratch
= list( c("bob", "charlie", "frank"), # student names
gradebook c(70,80,90), # grades from first test
c(75,85,88), # grades from second test
c(TRUE, FALSE,FALSE)) # TRUE for honors students
# If the item on the RHS of the = sign is itself a list, that will be
# inserted as a nested list.
#
# The following example inserts a nested list.
1]] = list( c("Robert", "Charles", "Francois"),
gradebook[[c("M.", "David", ""),
c("Rabinowitz", "Bush", "McDonald")
)
# It's easier to see the new structure of the list by using str
str(gradebook)
List of 4
$ :List of 3
..$ : chr [1:3] "Robert" "Charles" "Francois"
..$ : chr [1:3] "M." "David" ""
..$ : chr [1:3] "Rabinowitz" "Bush" "McDonald"
$ : num [1:3] 70 80 90
$ : num [1:3] 75 85 88
$ : logi [1:3] TRUE FALSE FALSE
Using RECURSIVE INDEXING to replace a single value deep inside of a list
############################################################################.
# Using RECURSIVE INDEXING to replace a single value deep inside of a list
############################################################################.
# Let's start again with the following data.
rm(list=ls()) # start from scratch
= list( c("bob", "charlie", "frank"), # student names
gradebook c(70,80,90), # grades from first test
c(75,85,88), # grades from second test
c(TRUE, FALSE,FALSE)) # TRUE for honors students
#-------------------------------------------------------------------------.
# The following example uses
# "recursive indexing" (i.e. 2 or more values in the [[double-brackets]])
# to pinpoint the name "charlie" in the 1st entry of the list.
# Therefore the name "charles" replaces that single item.
#-------------------------------------------------------------------------.
c(1,2)]] = "charles" # Change "charlie" to "charles"
gradebook[[str(gradebook)
List of 4
$ : chr [1:3] "bob" "charles" "frank"
$ : num [1:3] 70 80 90
$ : num [1:3] 75 85 88
$ : logi [1:3] TRUE FALSE FALSE
— Practice —
########################################################################.
# QUESTION - write code to
# add 5 points to the 2nd students grade in the 3rd vector
########################################################################.
Using [single-brackets] to replace items in a list
############################################################################.
# Using [single-brackets] to replace items in a list
############################################################################.
# When you use [single-brackets] on the left hand side (LHS) of the = sign,
# you can potentially identify more than one value from the list.
# Therefore the values from the RHS of the = sign may also contain more than
# one value. The values are replaced one by one from the values on the RHS to
# the positions in the list on the LHS.
# This is true both in the case that the RHS contains a list
# and in the case that the RHS contains a vector.
# Therefore it's very important to be aware of the type of data (list or vector)
# that is on the RHS of the = sign.
#
# See the examples below for more info.
############################################################################.
list1[single-brackets]=list2 #replace values in list1 with values from list2
# Let's start again with new data
rm(list=ls()) # start from scratch
= list( c("bob", "charlie", "frank"), # student names
gradebook c(70,80,90), # grades from first test
c(75,85,88), # grades from second test
c(TRUE, FALSE,FALSE)) # TRUE for honors students
# EXAMPLE:
#
# Replace the 2nd and 3rd items in the list on the left with the items
# in the list on the right.
#
# IMPORTANT - Notice that the item on the right is also a LIST.
c(2,3)] = list(c(81,82,83),
gradebook[c(91,92,93))
str(gradebook) # str of the new list
List of 4
$ : chr [1:3] "bob" "charlie" "frank"
$ : num [1:3] 81 82 83
$ : num [1:3] 91 92 93
$ : logi [1:3] TRUE FALSE FALSE
#-----------------------------------------------------------.
# ANOTHER EXAMPLE - Replace the names with new names.
#-----------------------------------------------------------.
# It makes no difference what is in the list on the RHS,
# just that it is a list with the correct number of values.
#
# Replace the 1st entry in the list with new names.
# Notice that the RHS of the = sign is a LIST
#-----------------------------------------------------------.
1] = list(c("sue", "joan", "eve"))
gradebook[str(gradebook) # str of the new list
List of 4
$ : chr [1:3] "sue" "joan" "eve"
$ : num [1:3] 81 82 83
$ : num [1:3] 91 92 93
$ : logi [1:3] TRUE FALSE FALSE
# You can even replace the names with any other type of info.
1] = list(c("sue", "joan", "eve","fran","goldie","laura","mindy"))
gradebook[str(gradebook) # str of the new list
List of 4
$ : chr [1:7] "sue" "joan" "eve" "fran" ...
$ : num [1:3] 81 82 83
$ : num [1:3] 91 92 93
$ : logi [1:3] TRUE FALSE FALSE
SOME_LIST[single-brackets] = SOME_VECTOR # uses values from the vector
#---------------------------------------------------------------------,
# SOME_LIST[single-brackets] = SOME_VECTOR
#---------------------------------------------------------------------,
# CAREFUL - if you have a VECTOR on the RHS then
# the values from the VECTOR on the RHS will replace
# the associated values from the LIST on the LHS.
#
# Generally speaking you probably don't want to to that.
# However, you should be aware of what happens if you try to do that.
#
# Let's start again with the following data
#---------------------------------------------------------------------,
rm(list=ls()) # start from scratch
= list( c("bob", "charlie", "frank"), # student names
gradebook c(70,80,90), # grades from first test
c(75,85,88), # grades from second test
c(TRUE, FALSE,FALSE)) # TRUE for honors students
#-------------------------------------------------------------------------.
# EXAMPLE:
#
# The following has only one value on the LHS but 3 values on the RHS.
# (Keep in mind - the LHS is a list but the RHS is a vector).
#
# This will cause only the first value from the RHS to be assigned to the
# single value on the LHS.
# i.e. the entire names vector (i.e. the 1st value on the LHS)
# is replaced with just "sue" (i.e. the 1st value on the RHS)
#
# In addition you get a WARNING since there are more values on the RHS than
# there should be.
#-------------------------------------------------------------------------.
1] = c("sue", "joan", "anne") gradebook[
Warning in gradebook[1] = c("sue", "joan", "anne"): number of items to replace
is not a multiple of replacement length
str(gradebook)
List of 4
$ : chr "sue"
$ : num [1:3] 70 80 90
$ : num [1:3] 75 85 88
$ : logi [1:3] TRUE FALSE FALSE
# The correct way to do this is to make the value on the RHS into a list.
1] = list ( c("sue", "joan", "anne") )
gradebook[str(gradebook)
List of 4
$ : chr [1:3] "sue" "joan" "anne"
$ : num [1:3] 70 80 90
$ : num [1:3] 75 85 88
$ : logi [1:3] TRUE FALSE FALSE
# Or another correct way to do this is to use [[double-brackets]] on the LHS
# and the vector on the RHS
1]] = c("leticia jones", "paulette cohen", "henrietta burns")
gradebook[[str(gradebook)
List of 4
$ : chr [1:3] "leticia jones" "paulette cohen" "henrietta burns"
$ : num [1:3] 70 80 90
$ : num [1:3] 75 85 88
$ : logi [1:3] TRUE FALSE FALSE
list1[1:4] = listWith2Values # recycling rule!!
#--------------------------------------------------------------------------.
# DON'T FORGET the recycling rule!!!
#--------------------------------------------------------------------------.
# Let's start again with the following data
rm(list=ls()) # start from scratch
= list( c("bob", "charlie", "frank"), # student names
gradebook c(70,80,90), # grades from first test
c(75,85,88), # grades from second test
c(TRUE, FALSE,FALSE)) # TRUE for honors students
#------------------------------------------------------------------------------.
# Replace entries 1,2,3,4 in gradebook with the entries in the list on the RHS.
# However there are only two entries in the list on the RHS. Therefore
# The entries on the RHS are recycled so that there are four entries
# in the list on the RHS.
#------------------------------------------------------------------------------.
1:4] = list(c("apple","banana","comquat","pear","peach"),
gradebook[c(1.99, 2.99, 3.99, 4.99, 5.99))
str(gradebook) # notice the vectors were recycled
List of 4
$ : chr [1:5] "apple" "banana" "comquat" "pear" ...
$ : num [1:5] 1.99 2.99 3.99 4.99 5.99
$ : chr [1:5] "apple" "banana" "comquat" "pear" ...
$ : num [1:5] 1.99 2.99 3.99 4.99 5.99