【问题标题】:Manipulate function with variable number of controls使用可变数量的控件操作函数
【发布时间】:2020-04-19 23:04:28
【问题描述】:

我的目标是拥有一个可以用 n 个数据集的数组调用的函数。该函数将调用manipulate 并创建一个带有控制框的绘图。此框将包含与数据集一样多的复选框(即 n)。每个复选框将允许在绘图上显示/隐藏相应的数据集。

为了简单起见,我假设每个数据集都是一个简单的字符串。


manipulate 在控件已知时可以正常工作。这里,对于单个控件:

manipulate(plot(0,0,main=b), b=checkbox(TRUE, 'bool'))

但是,就我而言,我需要可变数量的控件。我可以像这样创建一个控件列表:

dataList = c('a', 'b', 'c')
ctrls = list()
for(data in dataList) {
  ctrls[[data]] = checkbox(TRUE, data)
}

manipulate(plot(0,0), ctrls)

现在让我们看一个最小的用例:一个创建绘图的函数。它的标题将是所有具有值TRUE 的数据集名称的串联。

我最初的想法是将控件列表传递给函数,这样我就可以访问那里的每个控件。

foo <- function(dataList, ctrls) {
  print(dataList)
  title = ''
  for(data in dataList) {
    if (ctrls[[data]]) {                 # this fails
      title=cat(title, data)
    }
  }
  plot(0,0,main=title)
}

manipulate(foo(dataList, ctrls), ctrls)

上面的失败是因为ctrls[[data]]不是控件的值。

当控件被赋予列表中的manipulate 时,有没有办法访问控件的当前值?

【问题讨论】:

  • 计数数据时datalist的值不会是if (ctrls[[datalist]][data]
  • 不,我担心这行不通

标签: r


【解决方案1】:

经过一番折腾,我发现我可以在调用foo 之前利用get 函数从作用域中检索变量的值。

  1. 首先,我准备了控件列表

    series = list('a', 'b', 'c')
    controls = list()
    for(data in series) {
      controls[[data]] = checkbox(TRUE, data)
    }
    
  2. 然后我们有一个以列表为参数的回调函数

    foo <- function(data, bools) {
      t=""
      for(i in seq_along(data)) {
        if(bools[[i]]) t = c(t, data[[i]])
      }
      plot(0,0,main=t)
    }
    
  3. 终于来了manipulate。请注意,我正在将系列名称列表与其对应的复选框状态(TRUEFALSE)进行映射。

    manipulate(
      foo(lapply(series, function(e) get(e))), 
      controls
    )
    

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-02
    • 1970-01-01
    • 2014-10-07
    相关资源
    最近更新 更多