如何在purrr::map中访问cli进度条ID以实现进度更新?
解决方法:显式传递进度条标识或更新函数到内部函数
cli的进度条默认在当前上下文生效,要在内部函数中实现更新,核心是把进度条的引用(ID或更新函数)传递到内部函数里。以下是两种可行的实现方式:
方法1:传递进度条ID
先创建进度条并记录其ID,再将ID作为额外参数传入pmap调用,让内部函数通过ID定位到进度条完成更新:
library(purrr) library(cli) # 模拟待处理的多参数数据 df <- tibble::tibble(col1 = 1:10, col2 = 11:20) # 创建进度条并保存ID pb_id <- cli_progress_bar(total = nrow(df), name = "处理中...") # 定义内部函数,接收业务参数+进度条ID internal_process <- function(col1, col2, pb_id) { # 模拟耗时业务操作 Sys.sleep(0.2) # 通过ID更新进度条 cli_progress_update(id = pb_id) # 返回处理结果(可选) col1 * col2 } # 调用pmap,将pb_id作为额外参数传入 results <- pmap(df, internal_process, pb_id = pb_id) # 手动关闭进度条(可选,cli通常会自动处理完成状态) cli_progress_done(id = pb_id)
方法2:传递进度条更新函数
cli_progress_bar()会返回包含update方法的对象,直接提取这个更新函数传递给内部函数,调用更简洁:
library(purrr) library(cli) df <- tibble::tibble(col1 = 1:10, col2 = 11:20) # 创建进度条并提取更新函数 pb_update <- cli_progress_bar(total = nrow(df), name = "处理中...")$update internal_process <- function(col1, col2, pb_update) { Sys.sleep(0.2) # 直接调用更新函数完成进度更新 pb_update() col1 + col2 } results <- pmap(df, internal_process, pb_update = pb_update)
常见问题排查
如果之前用ID调用cli_progress_update未生效,大概率是这两个原因:
- 进度条ID没有正确传递到内部函数,导致内部无法定位到对应的进度条实例;
- 进度条的
total值与pmap实际处理的元素数量不匹配,或进度条在更新前已被关闭。
内容的提问来源于stack exchange,提问作者Fredrik Nylén
相关产品推荐
相关产品推荐

