Избегая печально известной конструкции eval (parse())

Хорошо, поэтому я запускаю некоторые циклы для обработки данных, хранящихся в объектах списка. Всегда помня о печально известном предостережении fortune, чтобы не использовать eval(parse(mystring)), я придумал это:

Rgames> bar
$foo
$foo$fast
[1] 1 2 3 4 5

$foo$slow
[1]  6  7  8  9 10


$oof
$oof[[1]]
[1]  6  7  8  9 10

$oof[[2]]
[1] 1 2 3 4 5


Rgames> rab<-'bar'
Rgames> do.call('$',list(as.name(rab),'oof'))
[[1]]
[1]  6  7  8  9 10

[[2]]
[1] 1 2 3 4 5

Обычно я выбираю список (из которых bar - один такой), а затем один элемент списка (например, oof), который содержит мои данные. Приведенный выше код делает то же самое, что и eval(parse(text=paste(rab,'$','oof',sep=''))).
Я делаю все это специально, потому что я хочу использовать имена списков, а не [[x]] обозначение как механизм безопасности (потому что не все объекты списка имеют свое содержимое в том же порядке). Должен ли я придерживаться совета DWin в R: eval (parse (...)) часто субоптимально?

Ответ 1

Используя get и [[:

bar <- list(foo = list(fast = 1:5, slow = 6:10),
            oof = list(6:10, 1:5))

rab <- 'bar'

get(rab)[['oof']]
# [[1]]
# [1]  6  7  8  9 10
# 
# [[2]]
# [1] 1 2 3 4 5

Ответ 2

Если имя вашего верхнего списка будет изменяться и к нему будет обращаться переменная с именем, тогда лучше разместить эти списки в другом списке, а затем вы можете получить доступ к списку, который хотите использовать с помощью [[. Также читайте fortune(312) и справку на ?'[['.

Затем вы можете получить доступ к фрагментам по-разному (подробнее на странице справки ?'[[').

mylist <- list()
mylist$bar <- bar

mylist[[rab]][['oof']]
#or
mylist[[ c(rab,'oof') ]]