捕获for循环迭代值,为动态生成的downloadHandler创建匿名函数

问题描述 投票:0回答:1

我正在开发一个 R Shiny 应用程序,构建一个图表列表,我希望通过单击每个图表下方的按钮来下载每个数据。

我的问题是,为处理

downloadHandler 
内容参数而创建的匿名函数仅在单击我的按钮时才会被解释,并且我无法检索用户按下哪个按钮来分派正确的数据下载。

plot_ids是plot_id的列表

["plot_1","plot_2",...]

plot_data 是一个命名的数据列表

["plot_1"=tibble(),"plot_2"=tibble(),...]

for (plot_id in plot_ids) {
  output[[plot_id]] <- downloadHandler(
      filename = function() {
        paste0("custom_export_", plot_id, ".csv")
      },
      content = function(file){
          write.csv(plot_data[[plot_id]], file, row.names = FALSE)
     }
  )
}

如果我生成多个绘图,则所有 downloadButton 和 downloadLink 都会链接到最后生成的绘图,因为

function(file){...}
在用户单击时被解释,然后plot_id 设置为 for 循环设置的最后一个值。

我还尝试使用

as.function()
生成匿名函数,以设置默认参数
function(file,local_plot_id=plot_id)
,或使用包装函数。

r shiny download anonymous-function
1个回答
0
投票

我终于使用

local
函数找到了问题的答案

local
在本地环境中计算表达式。它相当于
evalq
,只不过它的默认参数创建了一个新的空环境。这对于创建匿名递归函数非常有用,并且作为一种有限的命名空间功能,因为环境中定义的变量从外部不可见。

这是我的问题中本地使用的示例代码

for (plot_id in plot_ids) {
  output[[plot_id]] <- local({
    local_plot_id <- plot_id
    downloadHandler(
      filename = function() {
        paste0("custom_export_", local_plot_id, ".csv")
      },
      content = function(file){
          write.csv(plot_data[[local_plot_id]], file, row.names = FALSE)
      }
    )
  })
}
© www.soinside.com 2019 - 2024. All rights reserved.