``````###############################################################################.
###############################################################################.
##
## INTRODUCING [[double-bracket]] NOTATION FOR INDEXING LISTS (and also vectors)
##
## A new notation that we have not seen yet for indexing both vectors and lists
## is to use [[double-brackets]] to contain the index information instead
## of [single-brackets]. For example
##
##    someObject     # [single-bracket] notation
##    someObject[]   # [[double-bracket]] notation
##
## [[double-brackets]] have a slightly different meaning from [single-brackets].
##
## [[double-brackets]] work a little differently with vectors and with lists.
##
###############################################################################.
###############################################################################.``````
``````#----------------------------------------------------------------------.
# USING [[double-brackets]] WITH LISTS
#
# Using [[double-brackets]] to index into a LIST is similar to using
# double-brackets to index into a vector in the following way:
#
#     - You CAN use POSITIVE NUMBERS numbers in the [[double-brackets]]
#       With a LIST you MAY specify more than one POSITIVE number in the
#       [[double-brackets]]. (With vectors you are only able to specify
#       one positive number). We'll discuss below exactly how this works.
#
#  HOWEVER
#
#     - You CANNOT use negative numbers in the [[double-brackets]]
#
#     - You CANNOT use logical values in the [[double-brackets]]
#
#----------------------------------------------------------------------.

# setup a list to work with

gradebook = list( c("bob", "charlie", "frank"), # student names
c(70,80,90),                  # grades from first test
c(75,85,88),                  # grades from second test
c(TRUE, FALSE,FALSE))         # TRUE for honors students

``````[]
 "bob"     "charlie" "frank"

[]
 70 80 90

[]
 75 85 88

[]
  TRUE FALSE FALSE``````
``````# The following are ERRORS!

gradebook[[-1]]    # ERROR - don't use negative values in the [[double-brackets]]``````
``Error in gradebook[[-1]]: invalid negative subscript in get1index <real>``
``gradebook[[c(TRUE,FALSE)]] # ERROR - don't use logicals in [[double-brackets]]``
``Error in gradebook[[c(TRUE, FALSE)]]: attempt to select less than one element in integerOneIndex``

## 23.1 someList vs someList[]

``````#............................................................................
# QUESTION
#
# Take a minute to CAREFULLY NOTICE the difference between the following
# two commands.
#
# What is the difference???
#
#      []
#       "bob"     "charlie" "frank"
#
#
#       "bob" "charlie" "frank"
#
#............................................................................

gradebook  # return value is shown below``````
``````[]
 "bob"     "charlie" "frank"  ``````
``````# > gradebook
# []
#  "bob"     "charlie" "frank"

gradebook[]  # return value is shown below``````
`` "bob"     "charlie" "frank"  ``
``````# > gradebook[]
#  "bob" "charlie" "frank"

#............................................................................
#
#    gradebook    # returns a LIST of that contains ONE VECTOR
#
#    gradebook[]  # returns ONE VECTOR
#............................................................................

mode( gradebook )   # returns a list``````
`` "list"``
``mode( gradebook []) # returns a character vector``
`` "character"``
``````# Similarly for other positions ....

`` 70 80 90``
``mode( gradebook )   # list``
`` "list"``
``mode( gradebook []) # numeric``
`` "numeric"``

## 23.2 USING [single-brackets] TO INDEX INTO A LIST USING MORE THAN ONE POSITIVE NUMBER

``````#---------------------------------------------------------------------.
# USING [single-brackets] TO INDEX INTO A LIST
# USING MORE THAN ONE POSITIVE NUMBER
# is conceptually similar to using more than one positive number in single brackets
# with VECTORS.
#
# When indexing into a VECTOR you get back just the specified values in a new VECTOR.
#
# When indexing into a LIST  you get back just the specified values in a new LIST.
#---------------------------------------------------------------------.

gradebook[ c(1,2) ]   # a list of 2 items, i.e. the names and the test1 grades``````
``````[]
 "bob"     "charlie" "frank"

[]
 70 80 90``````
``mode(gradebook[c(1,2)])  # list``
`` "list"``

## 23.3 USING [[double-brackets]] TO INDEX INTO A LIST USING MORE THAN ONE POSITIVE NUMBER

``````#---------------------------------------------------------------------.
# RECURSIVE INDEXING
#
# WITH LISTS YOU CAN USE THE [[double-brackets]] with more than
# one position number - it applies the position numbers to the items
# you get back one at a time. This is known as "recursive indexing".
#---------------------------------------------------------------------.

gradebook[[c(1,2)]] # "charlie" - ie. from the 1st item in the list get the 2nd item``````
`` "charlie"``
``gradebook[[c(3,3)]] # 88 - i.e. from the 3rd item in the list get the 3rd item``
`` 88``
``gradebook[[c(3,2)]] # 85 - i.e. from the 3rd item in the list get the 2nd item``
`` 85``
``gradebook[]      # 75 85 95``
`` 75 85 88``
``gradebook[]      # TRUE FALSE FALSE``
``  TRUE FALSE FALSE``

## 23.4 Using the length function with lists (it can be tricky)

``````#--------------------------------------------.
# length( SOME_LIST )
#    returns the number of objects in the list
#
#     vs
#
# length( SOME_LIST[] )
#    returns the number of items in the first object in the list
#
#    vs
#
# length( SOME_LIST )
#    DONT DO THIS - IT ALWAYS RETURNS 1  - WHY?
#------------------------------------------------

rm(list=ls()) # Start from scratch
gradebook = list( c("bob", "charlie", "frank"), # student names
c(70,80,90),                  # grades from first test
c(75,85,88),                  # grades from second test
c(TRUE, FALSE,FALSE))         # TRUE for honors students

##############################################.
# Let's see the lengths of the following ...
##############################################.
length(gradebook)       # 4 - i.e. four objects in the list ``````
`` 4``
``length(gradebook[])  # 3 - i.e. three student names in the first object of the list``
`` 3``
``````# Be careful - if you use single brackets you will get back a "list".
# Therefore the following all return a list of length 1.
length(gradebook)    # 1 - i.e. this is a LIST that contains one vector``````
`` 1``
``````#############################.
# Let's see the actual values
#############################.

``````[]
 "bob"     "charlie" "frank"

[]
 70 80 90

[]
 75 85 88

[]
  TRUE FALSE FALSE``````
``````# The first item in the list (i.e. a full vector)
`` "bob"     "charlie" "frank"  ``
``````# A new list that contains just the 1st item of the original list vector)
``````[]
 "bob"     "charlie" "frank"  ``````
``#etc``

## 23.5 Summary - [single-brackets] vs [[double-brackets]]

``````###############################################################################.
#
# If you keep the following idea in mind, a lot of the rules become
# easier to remember:
#
#   - [single-brackets] are intended to allow you to identify MULTIPLE objects
#     in a list (and in a vector).
#
#   - [[double-brackets]] are intended to allow you to identify A SINGLE object
#     in a list (and in a vector too - we'll see this later). However, when
#     using a list, a SINGLE object might be a complete vector (or even
#     a complete list)
###############################################################################.``````

## 23.6 — Practice —

``````#########################################################.
# Use the following to answer the questions below
#########################################################.
rm(list=ls()) # Start from scratch
gradebook = list( c("bob", "charlie", "frank", "sam"),# student names
c(70,     80,        90,      100), # grades from 1st test
c(75,     85,        88,      92),  # grades from 2nd test
c(TRUE,   FALSE,     FALSE,   TRUE))# TRUE for honors students``````
``str(gradebook)  # see the structure``
``````List of 4
\$ : chr [1:4] "bob" "charlie" "frank" "sam"
\$ : num [1:4] 70 80 90 100
\$ : num [1:4] 75 85 88 92
\$ : logi [1:4] TRUE FALSE FALSE TRUE``````
``gradebook # (see the actual values)``
``````[]
 "bob"     "charlie" "frank"   "sam"

[]
  70  80  90 100

[]
 75 85 88 92

[]
  TRUE FALSE FALSE  TRUE``````
``# View(gradebooks)  # see the structure - try this command yourself``
``````##########################################################################.
# QUESTION
#
# NOTE that many R commands and functions require a vector, not a list.
# Therefore in these situations you will need to retrieve a vector
# from the list using [[double-brackets]]
#
# Given the gradebook data shown above, write a command to calculate
# the average on the 1st exam.
##########################################################################.``````
``````###########.
###########.

# Use [[double-brackets]] to get the data for the first exam
# and take the mean.

`` 85``
``````##############################.
# THE FOLLOWING IS WRONG!!!!
##############################.

# Note that the following does NOT produce the correct results
# since gradebook is a LIST and you cannot take the mean of a list.

mean(gradebook)  # WRONG - gradebook is a LIST - you need a VECTOR``````
``````Warning in mean.default(gradebook): argument is not numeric or logical:
returning NA``````
`` NA``
``````##########################################################################.
# QUESTION
#
# Notice that the data in the list above is a set of parallel vectors.
# Write a command to show the name of the students who got above average
# on the 1st test.
##########################################################################.``````
``````#####################################.
# ANSWER (using a few lines of code)
#####################################.

students [ test1 > mean(test1) ]  # show the students names``````
`` "frank" "sam"  ``
``````#####################################.
# ANSWER (in one line of code)
#####################################.

`` "frank" "sam"  ``
``````#############################################################################.
# QUESTION
# Write a command to return a vector that contains both the test1 and test2
# grades for the 3rd student
#############################################################################.``````
``````###########.
###########.
`` 90 88``

## 23.7 — Practice —

``````#########################################################.
# Use the following to answer the questions below
#########################################################.
rm(list=ls())  # start from scratch

c("Intro to IDS", "Prof. Jones"),
list( "Fall 2023",
c("bob", "charlie", "frank"), # student names
c(70,80,90),                  # grades from first test
c(75,85,88),                  # grades from second test
c(TRUE, FALSE,FALSE)),         # TRUE for honors students
list("Spring 2024",
c("bob", "charlie", "frank"), # student names
c(70,80,90),                  # grades from first test
c(75,85,88),                  # grades from second test
c(TRUE, FALSE,FALSE))         # TRUE for honors students
)``````
``str(gradebooks)  # see the structure``
``````List of 3
\$ : chr [1:2] "Intro to IDS" "Prof. Jones"
\$ :List of 5
..\$ : chr "Fall 2023"
..\$ : chr [1:3] "bob" "charlie" "frank"
..\$ : num [1:3] 70 80 90
..\$ : num [1:3] 75 85 88
..\$ : logi [1:3] TRUE FALSE FALSE
\$ :List of 5
..\$ : chr "Spring 2024"
..\$ : chr [1:3] "bob" "charlie" "frank"
..\$ : num [1:3] 70 80 90
..\$ : num [1:3] 75 85 88
..\$ : logi [1:3] TRUE FALSE FALSE``````
``gradebooks # (see the actual values)``
``````[]
 "Intro to IDS" "Prof. Jones"

[]
[][]
 "Fall 2023"

[][]
 "bob"     "charlie" "frank"

[][]
 70 80 90

[][]
 75 85 88

[][]
  TRUE FALSE FALSE

[]
[][]
 "Spring 2024"

[][]
 "bob"     "charlie" "frank"

[][]
 70 80 90

[][]
 75 85 88

[][]
  TRUE FALSE FALSE``````
``# View(gradebooks)  # see the structure - try this command yourself``
``mean( gradebooks[][] )``
`` 80``
``max( gradebooks[][], gradebooks[][] )``
`` 90``
``length(gradebooks)``
`` 3``
``length(gradebooks[c(1,2)])  ``
`` 2``
``gradebooks[c(1,2)]``
``````[]
 "Intro to IDS" "Prof. Jones"

[]
[][]
 "Fall 2023"

[][]
 "bob"     "charlie" "frank"

[][]
 70 80 90

[][]
 75 85 88

[][]
  TRUE FALSE FALSE``````
``str(gradebooks[c(1,2)])``
``````List of 2
\$ : chr [1:2] "Intro to IDS" "Prof. Jones"
\$ :List of 5
..\$ : chr "Fall 2023"
..\$ : chr [1:3] "bob" "charlie" "frank"
..\$ : num [1:3] 70 80 90
..\$ : num [1:3] 75 85 88
..\$ : logi [1:3] TRUE FALSE FALSE``````
``gradebooks[c(1,3)]``
``````[]
 "Intro to IDS" "Prof. Jones"

[]
[][]
 "Spring 2024"

[][]
 "bob"     "charlie" "frank"

[][]
 70 80 90

[][]
 75 85 88

[][]
  TRUE FALSE FALSE``````
``str(gradebooks[c(1,3)])``
``````List of 2
\$ : chr [1:2] "Intro to IDS" "Prof. Jones"
\$ :List of 5
..\$ : chr "Spring 2024"
..\$ : chr [1:3] "bob" "charlie" "frank"
..\$ : num [1:3] 70 80 90
..\$ : num [1:3] 75 85 88
..\$ : logi [1:3] TRUE FALSE FALSE``````
``length(gradebooks[[c(1,2)]])``
`` 1``
``gradebooks[[c(1,2)]]``
`` "Prof. Jones"``
``str(gradebooks[[c(1,2)]])``
`` chr "Prof. Jones"``
``length(gradebooks[])``
`` 5``
``gradebooks[]``
``````[]
 70 80 90``````
``mode( gradebooks[] )``
`` "list"``
``length( gradebooks[] )``
`` 1``
``gradebooks[][]  ``
`` 70 80 90``
``mode( gradebooks[][] )  ``
`` "numeric"``
``length( gradebooks[] )  ``
`` 1``