function - 包装到带有进度条的FOR循环

标签 function r loops expression wrapper

我喜欢在运行缓慢的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/

相关文章:

c - Smalltalk 风格的消息与 C 风格的函数

r - 函数总是返回数字(0)

R:将 mutate 调用从处理三个二进制变量调整为处理 n 个二进制变量

python - 打印行的次数与其值加一在其他行中出现的次数相同

MySQL重复数据删除与循环

sql - 编写 SQL 插入函数

Javascript onclick 事件未在 Firefox 中触发

php - 如何在 php 中找到计数为零的最小值?

r - 使用 mclapply、foreach 或 [r] 中的其他东西并行操作对象?

java - 使用 Java 处理负数时拆分数学表达式