1 상태표시12

work() 함수를 만들어서 무슨 작업인지는 모르지만 X초 동안 작업을 하게 만드는 도움 함수(helper function)를 만든다.

library(tidyverse)
library(progressr)

## 잠자기 함수 실행 도움 함수

work <- function(second = 0) {
  Sys.sleep(second)
  cat(second, "초 작업완료!\n")
}

work(1) # 1초 동안 쉼
1 초 작업완료!

각 작업의 단위는 1초로 1초에 해당되는 작업을 3번 작업 시킨다. 반환값이 없기 때문에 walk() 함수를 사용한다.

num_jobs <- rep(1,3)
walk(num_jobs, work)
1 초 작업완료!
1 초 작업완료!
1 초 작업완료!

작업이 진행되는 것을 보여주는 함수로 내장된 utils 팩키지 txtProgressBar() 함수가 있다. 앞의 함수를 조금 바꿔 입력받은 숫자를 제곱하는 결과를 반환하는 함수를 제작하나다. work_square() 함수는 1초 쉬고(작업하고) 제곱결과를 반환시킨다. 이를 txtProgressBar() 함수로 구현할 경우, setTxtProgressBar(), getTxtProgressBar() 함수를 사용해서 기능을 구현한다.

work_square <- function(x) {
  Sys.sleep(1)
  return(x*x)
}

input_val <- 1:5
pb <- txtProgressBar(max = length(input_val))

walk(input_val, function(x) {
  setTxtProgressBar(pb, getTxtProgressBar(pb)+1)
  work_square(x)
})
================================================================================
close(pb)

1부터 10까지 작업을 출력시키는 작업을 두가지 방식을 통해 비교해보자. 화면에 단순 출력하는 방식이 있는 반면에, txtProgressBar() 함수를 기본으로 다양하게 보기 좋게 출력하는 방식이 존재한다.

화면에 단순 출력

walk(1:10, function(i) {
  Sys.sleep(0.1)
  print(i)
})
[1] 1
[1] 2
[1] 3
[1] 4
[1] 5
[1] 6
[1] 7
[1] 8
[1] 9
[1] 10

상태표시 막대

pb <- txtProgressBar(title = "progress bar", min = 0, max = 10, style = 3, width = 50)

  |                                                        
  |                                                  |   0%
walk(1:10, function(i) {
  Sys.sleep(0.1)
  setTxtProgressBar(pb, i, label = paste( round(i/total*100, 0), "% done"))
})

  |                                                        
  |=====                                             |  10%
  |                                                        
  |==========                                        |  20%
  |                                                        
  |===============                                   |  30%
  |                                                        
  |====================                              |  40%
  |                                                        
  |=========================                         |  50%
  |                                                        
  |==============================                    |  60%
  |                                                        
  |===================================               |  70%
  |                                                        
  |========================================          |  80%
  |                                                        
  |=============================================     |  90%
  |                                                        
  |==================================================| 100%
close(pb)

2 progressr 팩키지3

progressr 팩키지 progress_bar를 사용하면 진행사항을 시각적으로 확인할 수 있다.

library(beepr)

handlers("beepr")

snail <- function(x, progress = FALSE) {
  
  if (progress) pb <- progress::progress_bar$new(total=length(x))
  
  walk(x, function(z) {
    if (progress) pb$tick()
    message(z, " 작업중 !!!") 
    work_square(z)
  })
}

x <- 1:10
# y <- snail(x)
y <- snail(x, progress=TRUE)

3 병렬 상태표시 막대4

furrr 팩키지를 사용하고 무명함수를 밖으로 빼서 명시적으로 future_map() 을 통해 동시 진행사항에 대한 파악도 가능하다.

library(furrr)

plan(multisession, workers = 2)

fn <- function(x, p) {
  p()
  Sys.sleep(.2)
  sum(x)
}

with_progress({
  p <- progressor(steps = length(x))
  result <- future_map(x, fn, p = p)
})
 

데이터 과학자 이광춘 저작

kwangchun.lee.7@gmail.com