Org Babel에서의 R 소스 코드 블록
Org Babel과 함께 R을 사용하면 통계 컴퓨팅, 데이터 분석, 그래픽 생성 및 재현 가능한 연구 논문을 위한 환경을 제공합니다. Org Mode의 R 코드 블록은 **ESS (Emacs Speaks Statistics)**와 통합되어 대화형 실행, 멀티 블록 상태 공유, 출판 품질의 그래픽 및 구조화된 테이블 내보내기를 지원합니다.
1. 설정 및 환경 구성
1.1 사전 요구 사항
- 작동하는 R 설치 (CRAN 바이너리 또는 소스에서 빌드).
- MELPA를 통해 설치된 ESS (Emacs Speaks Statistics) (세션 기반 평가 및 단계별 실행에 필요).
ob-R이org-babel-load-languages에서 활성화되어 있어야 함.
1.2 Emacs 구성 템플릿
다음 내용을 init.el에 추가하십시오:
;; 1. MELPA 구성
(require 'package)
(add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/") t)
(package-initialize)
;; 2. ESS가 로드되었는지 확인
(unless (package-installed-p 'ess)
(package-refresh-contents)
(package-install 'ess))
(require 'ess-r-mode)
;; 3. Org Babel에서 R 활성화
(org-babel-do-load-languages
'org-babel-load-languages
'((emacs-lisp . t)
(R . t)))
;; 4. 선택 사항: 대화형 보안 확인 프롬프트 없이 블록 실행
(setq org-confirm-babel-evaluate nil)
1.3 Windows 특정 설정
Microsoft Windows에서 Emacs에서 'The system cannot find the path specified' 오류가 발생하면 R 바이너리 경로를 명시적으로 설정하십시오 (기본 Babel 플래그 --slave --no-save 포함):
;; 64비트 Windows의 경우:
(setq org-babel-R-command "C:/Progra~1/R/R-4.3.0/bin/x64/R --slave --no-save")
참고: :session을 사용하면 org-babel-R-command는 무시되고 ESS의 inferior-ess-R-program이 대신 사용됩니다.
2. 실행 모드: 세션 및 ESS 통합
2.1 비세션 (:session none, 기본값)
별도의 배치 R 프로세스 (R --slave --no-save)에서 실행됩니다. 깨끗하고 격리되며 부작용이 없지만, 매번 모든 라이브러리와 데이터 로딩을 다시 실행합니다.
2.2 대화형 세션 (:session <이름>)
내부 ESS R 프로세스 (*<이름>*) 내에서 실행됩니다.
- 데이터셋, 라이브러리, 모델 및 변수는 동일한 세션 이름을 공유하는 여러 블록에서 지속됩니다.
- 대화형 검사, 디버깅 및 빠른 반복 작업 흐름을 가능하게 합니다.
#+PROPERTY: header-args:R :session *r-analysis* :results value :exports both
2.3 ESS를 사용한 대화형 디버깅 및 단계별 실행
R 블록 문제 해결 시:
- 세션으로 전환: R 블록 안에 커서를 두고
M-<down>(org-babel-pop-to-session) 또는C-c C-z(ess-switch-to-end-of-ESS)를 눌러 R REPL 버퍼로 이동합니다. - 환경 검사:
ls(),str(x),dim(x),summary(x)또는head(x)를 사용합니다. - 한 줄씩 단계별 실행:
- Org 블록 안에서
C-c '(org-edit-special)를 눌러 전용 ESS R 버퍼로 들어갑니다. C-c C-n(ess-eval-line-and-step) 또는C-c C-c(ess-eval-region-or-function-or-paragraph)를 사용하여 활성 R 프로세스에서 코드를 한 줄씩 실행합니다.C-c '를 눌러 Org 문서로 돌아갑니다.
- Org 블록 안에서
3. 결과 처리: 데이터 프레임, 값 및 테이블
3.1 표 형식 데이터 반환 (:results value table)
데이터 프레임, 행렬 또는 벡터를 반환할 때 Org Babel은 이를 기본 Org 테이블로 직접 변환합니다:
#+NAME: mtcars_summary
#+BEGIN_SRC R :session *r* :results value table :colnames yes
aggregate(mpg ~ cyl + gear, data=mtcars, FUN=mean)
#+END_SRC
#+RESULTS: mtcars_summary
| cyl | gear | mpg |
|-----+------+------------------|
| 4 | 3 | 21.5 |
| 6 | 3 | 19.7500000000000 |
| 8 | 3 | 15.0500000000000 |
| 4 | 4 | 26.92 |
| 6 | 4 | 19.75 |
| 4 | 5 | 28.2 |
| 6 | 5 | 19.7 |
| 8 | 5 | 15.4 |
- 데이터 프레임으로 작업할 때는 항상
:colnames yes를 추가하여 열 이름을 올바르게 유지하고 표시하십시오. - R에서 마지막으로 평가된 표현식의 값은 자동으로 반환됩니다 (명시적인
return()이 필요하지 않음).
3.2 콘솔 출력 캡처 (:results output)
stdout, 모델 출력 또는 요약 통계를 캡처하려면 :results output을 사용하십시오:
#+BEGIN_SRC R :session *r* :results output
fit <- lm(mpg ~ wt + hp, data=mtcars)
summary(fit)$coefficients
#+END_SRC
#+RESULTS:
: Estimate Std. Error t value Pr(>|t|)
: (Intercept) 37.2272694 1.59878754 23.284688 2.565459e-20
: wt -3.8778307 0.63273349 -6.128695 1.119647e-06
: hp -0.0317729 0.00902971 -3.518708 1.451229e-03
4. 그래픽 및 시각화
4.1 기본 그래픽 규칙 (Org $\ge$ 9.3)
그래픽을 생성하려면 :results에 file과 graphics를 모두 지정하고 :file에 출력 파일 이름을 추가하십시오:
:results graphics file :file <path.ext>
지원되는 파일 확장자 및 해당 R 장치:
- 벡터:
.pdf,.svg,.ps/.postscript,.tex(TikZ) - 래스터:
.png,.jpg/.jpeg,.tiff,.bmp - 기본 대체:
.png
#+BEGIN_SRC R :file figures/base_plot.png :results graphics file :width 600 :height 400 :res 120
plot(mtcars$wt, mtcars$mpg, pch=19, col="darkblue",
xlab="Weight (1000 lbs)", ylab="Miles per Gallon",
main="Fuel Economy")
abline(lm(mpg ~ wt, data=mtcars), col="red", lwd=2)
#+END_SRC
#+RESULTS:
[[file:figures/base_plot.png]]
4.2 중요한 ggplot2 / Lattice "Grid Graphics" 규칙
함정: Lattice (xyplot) 및 ggplot2 함수는 그래픽 객체를 반환합니다. 비대화형 배치 평가(비세션)에서 객체를 출력하지 않고 반환하면 빈/손상된 그래픽 파일이 생성됩니다!
Org Babel에서 ggplot2 / Lattice 플롯을 렌더링하는 세 가지 신뢰할 수 있는 방법이 있습니다:
방법 A: 명시적 print() (비세션에 권장)
#+BEGIN_SRC R :file figures/dist.png :results graphics file
library(ggplot2)
p <- ggplot(mtcars, aes(x=mpg)) + geom_histogram(bins=10, fill="steelblue")
print(p) # 명시적 print()가 그래픽 장치 렌더링을 트리거합니다
#+END_SRC
방법 B: :session 사용 (대화형으로 자동 출력)
#+BEGIN_SRC R :session *r* :file figures/dist.png :results graphics file
library(ggplot2)
ggplot(mtcars, aes(x=mpg)) + geom_histogram(bins=10, fill="steelblue")
#+END_SRC
방법 C: :results output graphics file 사용
#+BEGIN_SRC R :file figures/dist.png :results output graphics file
library(lattice)
xyplot(mpg ~ wt, data=mtcars)
#+END_SRC
5. R 그래픽 장치 헤더 인수
Org Babel은 R 그래픽 장치(png(), pdf(), svg() 등)의 매개변수에 직접 매핑되는 일급 헤더 인수를 제공합니다:
| 헤더 인수 | 기본값 | 설명 및 허용 값 |
|---|---|---|
:width | 7 (in) / 480 (px) | 장치 너비. |
:height | 7 (in) / 480 (px) | 장치 높이. |
:units | px (래스터), in (PDF) | 단위: "px", "in", "cm", "mm". |
:res | 72 | 인치당 픽셀(DPI) 단위의 명목 해상도. (선명한 래스터 플롯에 필수: 150-300 사용). |
:bg | "white" | 배경색 (예: "transparent", "#f7f7f7"). |
:fg | "black" | 전경색. |
:pointsize | 12 | 텍스트 렌더링을 위한 기본 포인트 크기. |
:family | "Helvetica" | 글꼴 패밀리 ("Helvetica", "Times", "Palatino", "Courier", "sans", "serif", "mono"). |
:quality | 75 | JPEG 품질 백분율 (1-100). |
:type | 플랫폼 기본값 | 비트맵 렌더러: "cairo", "quartz" 또는 "Xlib". |
:paper | "special" | PDF 용지 크기: "special", "a4", "letter", "a4r" 등. |
:R-dev-args | nil | 장치 함수에 직접 전달되는 추가 R 장치 인수의 원시 문자열. |
예제: 사용자 정의 치수를 가진 고해상도 Cairo SVG/PNG
#+NAME: custom_styled_plot
#+HEADER: :width 8 :height 5 :units in :res 300 :type cairo
#+HEADER: :R-dev-args bg="#fcfcfc"
#+BEGIN_SRC R :session *r* :file figures/styled_plot.png :results graphics file
library(ggplot2)
ggplot(diamonds[1:1000, ], aes(x=carat, y=price, color=cut)) +
geom_point(alpha=0.6) +
theme_minimal(base_family="sans") +
labs(title="Diamond Prices by Carat and Cut")
#+END_SRC
5.3 문서 글꼴 일치를 위한 TikZ LaTeX 그래픽
축 레이블과 수학적 주석이 문서와 정확히 동일한 LaTeX 글꼴을 공유하는 플롯을 생성하려면:
#+BEGIN_SRC R :file figures/model_plot.tex :results graphics file
plot(1:10, type="b", main="\\textbf{TikZ Plot with Math: } $\\int_0^1 x^2 dx$")
#+END_SRC
LaTeX/PDF로 내보낼 때 .tex 파일은 \input{figures/model_plot.tex}를 통해 기본적으로 포함됩니다!
6. 고급 형식 출력 (ASCII, Org 및 LaTeX)
6.1 ascii 패키지를 사용한 형식화된 Org 출력
R 패키지 ascii는 복잡한 비표 형식 R 객체(예: describe(), table() 또는 summary())를 기본 Org 구문으로 변환할 수 있습니다:
#+BEGIN_SRC R :session *r* :results output org
library(ascii)
options(asciiType = "org")
tab <- table(mtcars$cyl, mtcars$gear)
ascii(tab, caption="Cylinders vs Forward Gears")
#+END_SRC
#+RESULTS:
#+BEGIN_ORG
#+CAPTION: Cylinders vs Forward Gears
| | 3 | 4 | 5 |
|---+----+---+---|
| 4 | 1 | 8 | 2 |
| 6 | 2 | 4 | 1 |
| 8 | 12 | 0 | 2 |
#+END_ORG
6.2 LaTeX 내보내기를 위한 xtable을 사용한 출판 테이블
LaTeX 내보내기를 통해 PDF를 대상으로 하는 문서의 경우 :results output latex와 함께 xtable을 사용하십시오:
#+BEGIN_SRC R :results output latex :exports results
library(xtable)
fit <- lm(mpg ~ wt + hp, data=mtcars)
print(xtable(summary(fit), caption="Regression Estimates", label="tab:reg"),
comment=FALSE)
#+END_SRC
#+RESULTS:
#+BEGIN_LaTeX
\begin{table}[ht]
\centering
\begin{tabular}{rrrrr}
\hline
& Estimate & Std. Error & t value & Pr($>$$|$t$|$) \\
\hline
(Intercept) & 37.2273 & 1.5988 & 23.28 & 0.0000 \\
wt & -3.8778 & 0.6327 & -6.13 & 0.0000 \\
hp & -0.0318 & 0.0090 & -3.52 & 0.0015 \\
\hline
\end{tabular}
\caption{Regression Estimates}
\label{tab:reg}
\end{table}
#+END_LaTeX
7. 문제 해결 및 일반적인 함정
| 문제 | 원인 | 해결책 |
|---|---|---|
| ggplot2 또는 lattice가 빈/손상된 이미지를 생성함 | 반환된 그래픽 객체가 비세션 모드에서 명시적으로 출력되지 않음 | 플롯을 print(p)로 감싸거나, :session으로 전환하거나, :results output graphics file에 output을 추가하십시오. |
| 그래픽 파일이 생성되었지만 링크가 삽입되지 않음 | file 또는 graphics 키워드 누락 | 헤더에 :results graphics file이 있는지 확인하십시오 (Org $\ge$ 9.3에서는 두 단어 모두 필요). |
The system cannot find the path specified (Windows) | PATH 또는 사용자 지정 위치에 R 실행 파일이 없음 | init.el에서 (setq org-babel-R-command "path/to/R --slave --no-save")를 설정하십시오. |
| R 데이터 프레임에서 열이 행 0으로 변환됨 | 테이블 열 헤더가 관찰 데이터로 처리됨 | 블록 헤더 인수에 :colnames yes를 추가하십시오. |
| 세션 내 R이 대규모 계산에서 멈춤 | 블록이 Emacs 프로세스를 차단하고 있음 | 내부 ESS 버퍼(C-c C-z)로 전환하여 진행 상황을 모니터링하거나 C-c C-c로 중단하십시오. |
| 내보낸 문서에서 플롯이 흐릿함 | 기본 래스터 DPI(72)가 너무 낮음 | :res 300을 추가하고 그에 따라 :width와 :height를 조정하십시오. |