Динамически присваивать значение глубоко вложенному списку - PullRequest
1 голос
/ 26 сентября 2019

У меня есть вектор строк, например

> cc <- c("a", "b", "c")
> cc
[1] "a" "b" "c"

... и у меня есть список со структурой вроде:

> ll <- list("a" = list("b" = list("c" = "hola")))
> ll
$a
$a$b
$a$b$c
[1] "hola"

Какой самый простой способ динамического доступа кэлементы ll с использованием cc, чтобы я мог переназначить значения списка без создания нового списка?По сути, я хочу получить доступ к ссылке ll$a$b$c, а не к ее значению.

Жестко запрограммировав это, мы будем использовать такой синтаксис:

ll[[cc[1]]][[cc[2]]][[cc[3]]] <- ... # or
ll[["a"]][["b"]][["c"]] <- ... # or
ll$a$b$c <- ...

..что заставляет меня думать, что я хочу apply или lapply, но это не просто lapply(cc, ...), потому что это не рекурсивно применяет выбор к ll.Вместо этого он будет делать что-то вроде:

ll[c[1]] <- ...
ll[c[2]] <- ...
ll[c[3]] <- ...

Так что я подумал, что мне нужно будет использовать Reduce().Потому что, по сути, я пытаюсь применить функцию к переменной, затем применить функцию к результату, затем применить функцию к результату и т. Д .:

temp <-   ll[[c[1]]]
temp <- temp[[c[2]]]
temp <- temp[[c[3]]]
...

Но я неконечно, это также будет работать, потому что мы не сохраняем ссылку на ll[[c[1]]] в temp, мы сохраняем ее значение (вторая строка должна выдать ошибку).

У меня такое ощущение, чторешение будет включать Reduce, вызывая функцию доступа к списку как `[[` и, возможно, do.call(), но я заблудился.Есть идеи?

1 Ответ

2 голосов
/ 26 сентября 2019

Просто используйте:

ll[[cc]]
#[1] "hola"

Это не очень известное использование базового оператора [[, но это именно то, что вы ищете, мне кажется.

От?"[[", раздел «Рекурсивные (подобные списку) объекты»:

'[[' может быть применен рекурсивно к спискам, так что если единственный индекс 'i' является вектором длины 'p ',' alist [[i]] 'эквивалентно' alist [[i1]] ... [[ip]] ', предоставляя в списке все результаты, кроме окончательной индексации.

Конечно, вы также можете использовать его для переназначения значения:

ll[[cc]] <- "hello"
ll
#$a
#$a$b
#$a$b$c
#[1] "hello"
...