将进度条与 pmap 一起用于可以在 CRAN 上打包的功能
Using a progress bar with pmap for a function that can go in package on CRAN
我正在尝试编写一个函数来下载不同的向量并将它们组合到 return 数据框。我在 purrr 包中使用 pmap()
来遍历每个向量。我想从进度包中添加一个进度条,以向最终用户显示数据框的进度。这可以使用包 Read Me...
中建议的 <<-
代码的简化版本:
library(tidyverse)
library(progress)
f_one_col <- function(x, m, s){
d <- tibble(i = rnorm(n = 5, mean = m, sd = s))
names(d) <- x
# slow things down to check if the progress bar is appearing
Sys.sleep(1)
pb$tick()
return(d)
}
f <- function(d){
pb <<- progress_bar$new(total = nrow(d))
pb$tick(0)
d$col <- pmap(.l = d, .f = f_one_col)
pb$terminate()
rm(pb, envir = .GlobalEnv)
return(bind_cols(d$col))
}
d0 <- tibble(
x = c("a", "b", "c"),
m = c(10, 20, 30),
s = c(5, 200, 1000)
)
f(d = d0)
# # A tibble: 5 x 3
# a b c
# <dbl> <dbl> <dbl>
# 1 6.50 70.8 -1071.
# 2 3.51 -52.0 -542.
# 3 3.76 369. -351.
# 4 11.4 171. 1745.
# 5 0.421 111. 1886.
但是当我将函数放入我的 R 包时,我在构建检查中遇到错误...
no visible binding for '<<-' assignment to 'pb'
从我目前所读的内容来看,使用 <<-
似乎是 CRAN 的禁忌。有没有其他方法可以使用进度条而不必使用 <<-
或允许 <<-
在包中的 hacky 方法?
遵循进度包 Readme.md 文件中 progress_progress
的示例。超级分配不能保证分配到全局环境中,如果首先在父环境中查找具有它分配给的符号的对象,并且只有在找不到时才在全局环境中创建一个新对象,作为一种倒退。阅读help("<<-")
。这种“有用的”回退行为不是您在包代码中应该依赖的(它也完全不直观,在其他语言中没有明显的类似物,并且是创建具有意外副作用的代码的好方法!)
包函数不应该在全局环境中改变状态,那是一种可怕的代码味道。
通过将辅助函数 (f_one_col()
) 直接放在 pmap()
函数中,避免必须使用 <<-
。
... 并使用 pmap_dfc()
而不是 pmap()
和 bind_cols()
f <- function(d){
pb <- progress_bar$new(total = nrow(d))
pb$tick(0)
pmap_dfc(
.l = d,
.f = function(x, m, s){
d <- tibble(i = rnorm(n = 5, mean = m, sd = s))
names(d) <- x
pb$tick()
Sys.sleep(0.5)
return(d)
})
}
我正在尝试编写一个函数来下载不同的向量并将它们组合到 return 数据框。我在 purrr 包中使用 pmap()
来遍历每个向量。我想从进度包中添加一个进度条,以向最终用户显示数据框的进度。这可以使用包 Read Me...
<<-
代码的简化版本:
library(tidyverse)
library(progress)
f_one_col <- function(x, m, s){
d <- tibble(i = rnorm(n = 5, mean = m, sd = s))
names(d) <- x
# slow things down to check if the progress bar is appearing
Sys.sleep(1)
pb$tick()
return(d)
}
f <- function(d){
pb <<- progress_bar$new(total = nrow(d))
pb$tick(0)
d$col <- pmap(.l = d, .f = f_one_col)
pb$terminate()
rm(pb, envir = .GlobalEnv)
return(bind_cols(d$col))
}
d0 <- tibble(
x = c("a", "b", "c"),
m = c(10, 20, 30),
s = c(5, 200, 1000)
)
f(d = d0)
# # A tibble: 5 x 3
# a b c
# <dbl> <dbl> <dbl>
# 1 6.50 70.8 -1071.
# 2 3.51 -52.0 -542.
# 3 3.76 369. -351.
# 4 11.4 171. 1745.
# 5 0.421 111. 1886.
但是当我将函数放入我的 R 包时,我在构建检查中遇到错误...
no visible binding for '<<-' assignment to 'pb'
从我目前所读的内容来看,使用 <<-
似乎是 CRAN 的禁忌。有没有其他方法可以使用进度条而不必使用 <<-
或允许 <<-
在包中的 hacky 方法?
遵循进度包 Readme.md 文件中 progress_progress
的示例。超级分配不能保证分配到全局环境中,如果首先在父环境中查找具有它分配给的符号的对象,并且只有在找不到时才在全局环境中创建一个新对象,作为一种倒退。阅读help("<<-")
。这种“有用的”回退行为不是您在包代码中应该依赖的(它也完全不直观,在其他语言中没有明显的类似物,并且是创建具有意外副作用的代码的好方法!)
包函数不应该在全局环境中改变状态,那是一种可怕的代码味道。
通过将辅助函数 (f_one_col()
) 直接放在 pmap()
函数中,避免必须使用 <<-
。
... 并使用 pmap_dfc()
而不是 pmap()
和 bind_cols()
f <- function(d){
pb <- progress_bar$new(total = nrow(d))
pb$tick(0)
pmap_dfc(
.l = d,
.f = function(x, m, s){
d <- tibble(i = rnorm(n = 5, mean = m, sd = s))
names(d) <- x
pb$tick()
Sys.sleep(0.5)
return(d)
})
}