7

Say I have the following list (note the usage of non-syntactic names)

list <- list(A  = c(1,2,3),
            `2` = c(7,8,9))

So the following two way of parsing the list works:

`$`(list,A)
## [1] 1 2 3

`$`(list,`2`)
## [1] 7 8 9

However, this way to proceed fails.

id <- 2 
`$`(list,id)
## NULL

Could someone explain why the last way does not work and how I could fix it? Thank you.

user438383
  • 5,716
  • 8
  • 28
  • 43
  • 1
    This is because `list` (the object) does not have a variables named `id`. Try, ```list$id <- 2; `$`(list,id)```, it does work; or am I missing something? – Maël Jan 24 '22 at 10:44
  • 1
    Thank you for your answer, @Maël. This indeed works. However, as you mention, the object `list` does not contain any variable called `id`, but the content of `id` is `2`, which is actually included in the list. So, I would like to extract `c(7,8,9)` somehow using another object (in this case, `id`). I hope this clarifies it. – Álvaro A. Gutiérrez-Vargas Jan 24 '22 at 10:54
  • 1
    It is clearer now yes. I think the question is not only relevant for non-syntactic names but also for syntactic ones, see ```id <- "A"; `$`(list,id)``` – Maël Jan 24 '22 at 13:08

2 Answers2

2

I am also trying to get a better grasp of non-syntactic names. Unfortunately, more complex patterns of their use are hard to find. First, read ?Quotes and what backticks do.

For the purpose of learning here is some code:

list <- list(A  = c(1,2,3),
             `2` = c(7,8,9))

id <- 2 

id_backtics <- paste0("`", id,"`")

text <- paste0("`$`(list, ", id_backtics, ")")
text
#> [1] "`$`(list, `2`)"

eval(parse(text = text))
#> [1] 7 8 9

Created on 2022-01-24 by the reprex package (v2.0.1)

Claudiu Papasteri
  • 2,469
  • 1
  • 17
  • 30
2

Your id is a "computed index", which is not supported by the $ operator. From ?Extract:

Both [[ and $ select a single element of the list. The main difference is that $ does not allow computed indices, whereas [[ does. x$name is equivalent to x[["name", exact = FALSE]].

If you have a computed index, then use [[ to extract.

l <- list(a = 1:3)
id <- "a"

l[[id]]
## [1] 1 2 3

`[[`(l, id) # the same
## [1] 1 2 3

If you insist on using the $ operator, then you need to substitute the value of id in the $ call, like so:

eval(bquote(`$`(l, .(id))))
## [1] 1 2 3

It doesn't really matter whether id is non-syntactic:

l <- list(`!@#$%^` = 1:3)
id <- "!@#$%^"

l[[id]]
## [1] 1 2 3

`[[`(l, id)
## [1] 1 2 3

eval(bquote(`$`(l, .(id))))
## [1] 1 2 3
Mikael Jagan
  • 9,012
  • 2
  • 17
  • 48