R로 분석을 하고 나서 주기적으로 돌아가는 배치 프로그램을 작성할 경우가 많다. 이 배치 프로그램을 제작하는 것은 사실 분석 프로그램을 작성하는 것과는 사뭇 다른점이 있으며, 이 부분을 제외하고 나서도 다른 언어하고 상당히 다른 동작을 하는 부분을 쉽게 찾을 수 있다.
가장 먼저 난감했던 점은 대다수의 프로그래밍 언어들이 다른 소스 스크립트나 리소스들을 참조할 때 메인 스크립트 소스파일의 경로를 기준으로 상대적인 경로나 혹은 절대경로로 다른 리소스에 접근하는데, R의 경우 그렇지는 않다는 점이었다.
문제는 Rscript 배치 수행시 working directory기준으로 여타 리소스에 대한 접근 경로를 계산하는 것이다. 이 덕분에 기존 통념대로 스크립트를 작성하고 원 메인 스크립트 소스와 다른 경로를 기준으로 스크립트를 포함하려 source()
와 같은 명령어를 사용하려 한다면 전혀 엉뚱한 경로의 파일을 소싱하려 시도하게 된다. 이런 문제 때문에 필자도 몇시간을 허비한 경험이 있고, 이 때문에 개인적으로 관련 함수를 개발하여 사용하고 있다.
이 이외에 로깅을 하기 위해 메지시들을 남기게 되는데, 필요한 로깅만을 남기기 위한 몇몇 작업이 필요하다. 이에 대한 내용은 이 글에서 확인해 볼 수 있고 필요에 따라 적절한 메시지를 남길 수 있게끔 조절 가능하니 참고하길 바란다.
필자의 배치 스크립트 헤더 방식은 이렇다.
# !/usr/bin/Rscript --vanilla
# 경고 출력 안함
options(warn = -1)
# all message(에러, 경고) to stdout
sink(stdout(), type = "message")
## 설치 방법 library(devtools) install_github('RscriptUtils',
## 'haven-jeon')
library(RscriptUtils)
# 이 파일을 기준으로 상대 경로로 foo.R에 접근함
source_on_rscript("../lib/foo.R")
# working dir에서 이 파일로의 상대 경로를 얻음
rel_path <- get_relative_rscript_path()
# 이 파일을 기준으로 하는 상대 경로로 bar.RData를 접근해서 로딩
load(file.path(rel_path, "..", "data", "bar.RData"))
위 코드가 아마도 당장에는 뭔 의미인지 모를 사람들이 대부분일 것이다. 하지만 분석 결과를 활용하는 R 배치 스크립트를 작성한다면, 위 코드가 상당히 많은 부분 도움이 될 것이라 생각한다. RscriptUtils
패키지는 적당한 시기에 공개할 예정인데, 배치 작성에 문제나 불편함이 보일때마다 함수를 보강해 나갈 생각이다.
R 배치 프로그램 작성시 문제들과 나의 해결책 by from __future__ import dream is licensed under a Creative Commons Attribution-NonCommercial 4.0 International License.