我喜欢在运行缓慢的for
循环时使用进度条。使用几个助手可以轻松完成此操作,但我确实喜欢tcltk软件包中的tkProgressBar
。
一个小例子:
pb <- tkProgressBar(title = "Working hard:", min = 0, max = length(urls), width = 300)
for (i in 1:300) {
# DO SOMETHING
Sys.sleep(0.5)
setTkProgressBar(pb, i, label=paste( round(i/length(urls)*100, 0), "% ready!"))
}
close(pb)
而且我想设置一个小函数以将其存储在名为
forp
的.Rprofile中(如:带有Progressbar的for循环),以类似于for
的方式进行调用,但带有自动添加的进度条-但不幸的是,不知道如何实现并获取循环功能的expr
部分。我用do.call
做过一些实验,但没有成功:(虚构的工作示例(其作用类似于
for
循环,但会创建一个TkProgressBar
并在每次迭代中自动对其进行更新):forp (i in 1:10) {
#do something
}
更新:我认为问题的核心是如何编写一个函数,该函数不仅在函数后的括号中具有参数(例如:
foo(bar)
),而且还可以处理在右括号后指定的expr
,例如:< cc>。赏金优惠:可以找到可以修改my suggested function以使其像基本
foo(bar) expr
循环的语法那样工作的所有答案。例如。代替> forp(1:1000, {
+ a<-i
+ })
> a
[1] 1000
它可以这样称呼:
> forp(1:1000) {
+ a<-i
+ }
> a
[1] 1000
只是为了再次阐明任务:我们如何抓住函数调用的
for
部分?恐怕这是不可能的,但是会给职业玩家几天的赏金:)
最佳答案
考虑到提供的其他答案,我怀疑很难完全按照您指定的方式进行操作。
但是,我相信,如果您创造性地使用plyr
包,有一种非常接近的方法。诀窍是使用l_ply
将列表作为输入而不创建任何输出。
该解决方案与您的规范之间的唯一真正区别是,您可以在for
循环中直接在同一环境中修改变量。使用l_ply
您需要发送一个函数,因此如果要在父环境中修改内容,则必须更加小心。
尝试以下方法:
library(plyr)
forp <- function(i, .fun){
l_ply(i, .fun, .progress="tk")
}
a <- 0
forp(1:100, function(i){
Sys.sleep(0.01)
a<<-a+i
})
print(a)
[1] 5050
这将创建一个进度条,并在全局环境中修改
a
的值。编辑。
为避免疑问:参数
.fun
始终是具有单个参数的函数,例如.fun=function(i){...}
。例如:
for(i in 1:10){expr}
等效于forp(1:10, function(i){expr})
换一种说法:
i
是循环的循环参数.fun
是具有单个参数的函数i
关于function - 包装到带有进度条的FOR循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7349570/