[R] 반복문 프로그램 진행 경과 막대로 나타내기 (progress bar)



R에서 for loop 반복문을 실행하거나 데이터를 다운로드 하다보면 전체 수행 회수 중에서 현재 어디까지 진행이 된 것인지 중간 중간 확인해보고 싶을 때가 있습니다. 특히 연산이 오래걸리고 for loop 반복회수가 많거나, 대용량 데이터를 다운로드 해야할 경우라면 얼마나 진행이 되었고, 얼마나 더 기다려야 하는건지 중간에 확인할 수 없다면 무척 답답할 것입니다.


이번 포스팅에서는 R의 반복문이나 다운로드의 진행 경과 (progress status) 를 출력해주는 방법을 소개하겠습니다.


'progress' 패키지를 활용하여

(1) 순환문 진행상태를 막대(bar), 비율(percent), 추정 완료시간 출력하기

(2) 순환문 진행상태를 현재까지 수행 개수(current), 총 수행 (예정) 개수(total), 현재까지 상세 소요 시간(elapsedfull) 출력하기

(3) 다운로드의 진행 경과 출력하기 (download progress)


'randomForest' 패키지를 사용하여

(4) Random Forest 분석의 진행상태 출력하기



[ R 'progress' 패키지를 사용한 진행 경과 막대 출력하기 ]







  (1) 순환문 진행상태를 막대(bar), 비율(percent), 추정 완료시간 출력하기


R의 'progress' 패키지는 진행 경과를 막대 형태로 출력해주는데 있어 다양한 매개변수를 사용하여 원하는 형식으로 진행 상태를 출력(Configurable progress bars)할 수 있게 해줍니다.

아래의 (1) ~ (3) 까지는 R의 'progress' 패키지를 사용합니다. 처음 사용하는 분이라면 'progress' 패키지 설치부터 해주세요.



## 'progress' Package: Configurable progress bars

install.packages("progress")
library(progress)

 



'progress' 패키지의 진행 상태 막대 (Progress bar) 는 R6 객체이며, progress_bar$new() 를 사용해서 진행상태 막대 R6 객체를 생성할 수 있습니다.


progress_bar$new() 안의 total 은 진행상태를 확인하는 총 회수 (tick 의 사전적 의미는 시계가 '똑딱 똑딱 움직이는 소리'를 나타냄) 를 지정해주는 매개변수입니다. 이 total 값이 알려져있지 않을 때는 NA 를 사용하면 되며, 기본값은 total=100 입니다.


그리고, 아래의 10,000회를 반복하는 for loop 예제문에서 Sys.sleep() 는 괄호 안에 지정한 시간만큼 R 실행을 잠깐 멈추라는 뜻입니다. 아래 예의 for loop 반복문 안에는 특별히 연산을 수행하는 것이 없으므로 Sys.sleep(1 / 1000) * 10,000 회 수행하는 만큼의 시간이 걸리겠네요.


기본 설정값(default)만 사용한 결과, 아래처럼 진행 경과 막대(progress bar)와 비율(percent) 이 매우 간결한 형태로 출력이 되었습니다.


그리고 100% 모두 진행이 되면 콘솔 창에서 진행 경과 막대 출력 결과가 사라집니다.(clear=TRUE 가 기본 설정이므로)



pb <- progress_bar$new(total = 10000)
for (i in 1:10000) {
  pb$tick()
  Sys.sleep(1 / 1000) # Suspend execution of R expressions for a specified time interval
}





앞서 진행 경과 막대(progress bar)가 설정가능하다("Configurable")고 말씀드렸는데요, 이는progress_bar$new() 로 R6 객체를 만들 때 "format 매개변수"에 다양한 "설정 값 (Token)" 들 중에서 원하는 설정 값을 선택해서 넣어주면 됩니다.

아래의 예에서는 format 매개변수에 Token 값으로
  • :bar   >> 진행 경과 막대 출력
  • :percent  >> 진행 경과 비율 출력
  • :eta   >> 진행 완료 추정 시간 출력
을 사용하였습니다. 그러면 아래의 화면 캡쳐처럼 for loop 문의 진행경과가 막대 형태와 퍼센트로 출력이 되고, 추정 완료 시간도 같이 출력됩니다.

clear = FALSE 로 매개변수를 설정해주면 진행 경과가 100%가 된 이후에도 '진행 경과 막대' 출력 결과가 사라지지 않고 그대로 남아있게 됩니다.


## format: The format of the progress bar with :bar, :percent, :eta tokens
pb <- progress_bar$new(
  format = " Progress: [:bar] :percent, Estimated completion time: :eta",
  total = 10000, # totalnumber of ticks to complete (default 100)
  clear = FALSE, # whether to clear the progress bar on completion (default TRUE)
  width= 80 # width of the progress bar
  )


for (i in 1:10000) {
  pb$tick() # increases the number of ticks by one (or another specified value)
  Sys.sleep(1 / 1000)
}





위의 progress_bar$new() 에서 width 매개변수는 '진행 경과 막대'의 폭을 설정해줄 때 사용합니다. R의 기본 설정 폭의 값은 options('width') 로 확인해볼 수 있는데요, 115 이군요. 위의 예에서는 width=80 으로서 기본 설정값보다는 좀더 폭이 좁게 조정해 본 것입니다.



options('width')
# $width
# [1] 115

 




  (2) 순환문 진행상태를 현재까지 tick 개수(current), 총 tick 개수(total),

      현재까지 상세 소요 시간(elapsedfull) 출력하기


이번에는 진행 상태를 현재 tick 의 회수 (current), 총 tick 의 회수 (total), 그리고 현재까지 실제 소요 시간(elapsedfull) 을 출력해보겠습니다.

  • :current       >> 현재까지 tick 개수
  • :total          >> 총 tick 개수
  • :elapsedfull  >> 현재까지 소요된 상세 시간 (hh:mm:ss format)


## format: The format of the progress bar with :current, :total, :elapsedfull tokens
pb <- progress_bar$new(
  format = "Current tick number :current / Total tick number :total, Elapsed time :elapsedfull",
  total = 10000, # totalnumber of ticks to complete (default 100)
  clear = FALSE, # whether to clear the progress bar on completion (default TRUE)
  width= 80 # width of the progress bar
)


for (i in 1:10000) {
  pb$tick() # increases the number of ticks by one (or another specified value)
  Sys.sleep(1 / 1000)
}






  (3) 다운로드의 진행 경과 출력하기 (download progress)


progress_bar$new() 의 R6 객체에 format 설정을 통해서 다운로드 할 때 파일 크기는 얼마이고, 그중에서 몇 바이트를 다운로드 진행했는지도 경과 막대로 표시할 수 있습니다.


  • :rate       >> 다운로드 비율, 초당 Bytes
  • :elapsed  >> 소요 시간 (단위: 초)



## Download (or other) rates
pb <- progress_bar$new(
  format = " downloading foobar at :rate, got :bytes in :elapsed",
  clear = FALSE, total = NA, width = 60)

f <- function() {
  for (i in 1:100) {
    pb$tick(sample(1:100 * 1000, 1))
    Sys.sleep(2/100)
  }
  pb$tick(1e7)
  invisible()
}
f()






  (4) randomForest' 패키지를 사용하여 Random Forest 분석의 진행상태 출력하기


Decision Tree를 여러개 수행해서 결과를 평균내거나 다수결로 취하는 ensemble 기법인 Random Forest 의 경우, R의 random forest 패키지의 do.trace 옵션을 사용하면 진행 경과를 출력할 수 있습니다.

do.trace=TRUE 또는 do.trance=integer (로그를 콘솔에 남기기 원하는 간격) 의 형식으로 입력해주시면 됩니다.

아래 예시 코드는 ntree=10000 으로 해놓고, 1000회 별로 콘솔에 로그를 남기게 됩니다.



library("randomForest")
set.seed(1)

rf = randomForest(Species~., data=iris,
    ntree=10000,
    proximity=T,
    do.trace=1000) # <--- 추가


ntree OOB 1 2 3
1000: 4.67% 0.00% 6.00% 8.00%
2000: 4.00% 0.00% 6.00% 6.00%
3000: 4.00% 0.00% 6.00% 6.00%
4000: 4.00% 0.00% 6.00% 6.00%
5000: 4.00% 0.00% 6.00% 6.00%
6000: 4.00% 0.00% 6.00% 6.00%
7000: 4.00% 0.00% 6.00% 6.00%
8000: 4.00% 0.00% 6.00% 6.00%
9000: 4.67% 0.00% 6.00% 8.00%
10000: 4.67% 0.00% 6.00% 8.00%

 



[ Reference ]

* Pakcage 'progress' : https://cran.r-project.org/web/packages/progress/progress.pdf


이번 포스팅이 많은 도움이 되었기를 바랍니다.

행복한 데이터 과학자 되세요! :-)



Posted by R Friend Rfriend

댓글을 달아 주세요