Wrapper to FOR loops with progress bar

前端 未结 8 697
走了就别回头了
走了就别回头了 2021-01-31 19:57

I like to use a progress bar while running slow for loops. This could be done easily with several helpers, but I do like the tkProgressBar from tcl

8条回答
  •  北荒
    北荒 (楼主)
    2021-01-31 20:14

    The problem is that the for-loop in R is treated special. A normal function is not allowed to look like that. Some small tweaks can make it loop pretty close though. And as @Aaron mentioned, the foreach package's %dopar% paradigm seems like the best fit. Here's my version of how it could work:

    `%doprogress%` <- function(forExpr, bodyExpr) {
       forExpr <- substitute(forExpr)
       bodyExpr <- substitute(bodyExpr)
    
       idxName <- names(forExpr)[[2]]
       vals <- eval(forExpr[[2]])
    
       e <- new.env(parent=parent.frame())
    
       pb <- tkProgressBar(title = "Working hard:", min = 0, max = length(vals), width = 300)
       for (i in seq_along(vals)) {
         e[[idxName]] <- vals[[i]]
         eval(bodyExpr, e)
         setTkProgressBar(pb, i, label=paste( round(i/length(vals)*100, 0), "% ready!"))
       }
    }
    
    
    # Example usage:
    
    foreach(x = runif(10)) %doprogress% { 
      # do something
      if (x < 0.5) cat("small\n") else cat("big")
    }
    

    As you can see, you have to type x = 1:10 instead of x in 1:10, and the infix operator %% is needed to get hold of the looping construct and the loop body. I currently don't do any error checking (to avoid muddling the code). You should check the name of the function ("foreach"), the number of arguments to it (1) and that you actually get a valid loop variable ("x") and not an empty string.

提交回复
热议问题