【问题标题】:Avoiding the infamous "eval(parse())" construct避免臭名昭著的“eval(parse())”构造
【发布时间】:2012-11-18 18:45:42
【问题描述】:

好的,所以我正在运行一些循环来处理存储在列表对象中的数据。记住臭名昭著的 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(...)) is often suboptimal 中的建议吗?

【问题讨论】:

    标签: r parsing expression eval interpreter


    【解决方案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') ]]
      

      【讨论】:

      • 这是一个很好的观点,但它确实假设我有足够的组织:-) 提前知道我将使用的所有列表。
      • @CarlWitthoft,任何时候你去使用一个不在你的主列表中的列表,你都可以使用get添加它。
      • 或者globalenv()[["mylist"]] - 列表和环境的工作方式非常相似。
      • @hadley,我考虑过提出同样的建议,但应该注意(这是给正在阅读本文的其他人,而不是 Hadley),如果新用户开始过度使用“globalenv()”,这可能会变得非常危险和类似的,而不是考虑更好的方法。
      猜你喜欢
      • 2015-03-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-09
      • 2011-04-14
      相关资源
      最近更新 更多