Makefiles cho các dự án R / LaTex


Lê Phúc Tâm
6 năm trước
Hữu ích 7 Chia sẻ Viết bình luận 0
Đã xem 4266

Make là một công cụ tuyệt vời được sử dụng bởi các lập trình viên để xây dựng phần mềm, nhưng nó có thể được sử dụng nhiều hơn thế. Tôi sử dụng  make bất cứ khi nào tôi có một dự án lớn liên quan đến các tệp R và tệp LaTeX, có nghĩa là tôi sử dụng nó cho hầu hết tất cả các giấy tờ tôi viết và hầu hết các báo cáo tư vấn tôi tạo ra.

Nếu bạn đang sử dụng máy Mac hoặc Linux, bạn đã  make cài đặt. Nếu bạn đang sử dụng Windows và đã   cài đặt Rtools , thì bạn cũng sẽ có  make. Nếu không, người dùng Windows sẽ cần phải cài đặt nó. Một triển khai là trong  GnuWin .

Một dự án điển hình của tôi sẽ bao gồm một số tệp R chứa mã phù hợp với một số mô hình và tạo các bảng và biểu đồ. Tôi cố gắng thiết lập mọi thứ để tôi có thể tạo lại tất cả các kết quả bằng cách chạy các tệp R. Sau đó, tôi sẽ có một tệp LaTeX chứa giấy hoặc báo cáo tôi đang viết. Các bảng và biểu đồ được tạo bởi R được kéo vào tệp LaTeX. Do đó, tất cả những gì tôi cần làm là chạy tất cả các tệp R, sau đó xử lý tệp tex và giấy / báo cáo được tạo.

Make dựa vào a  Makefile để xác định nó phải làm gì Về cơ bản, một  Makefile tệp chỉ định những tệp nào phải được tạo trước và cách tạo tệp. Vì vậy, tôi cần một  Makefile chỉ định rằng tất cả các tệp R phải được xử lý trước, và sau đó là tệp LaTeX.

Cái hay của a  Makefile là nó sẽ chỉ xử lý các tệp đã được cập nhật. Nó đủ thông minh để không chạy lại mã nếu nó đã được chạy. Vì vậy, nếu không có gì thay đổi, chạy làm không có gì. Nếu chỉ thay đổi tệp tex, chạy make sẽ biên dịch lại tài liệu tex. Nếu mã R đã thay đổi, chạy make sẽ chạy lại mã R để tạo các bảng và biểu đồ mới, sau đó biên dịch lại tài liệu tex. Tất cả tôi làm là loại  make và nó chỉ ra những gì được yêu cầu.

Makefile cho LaTeX

Thật dễ dàng để biết liệu tài liệu latex có cần biên dịch hay không -  make đơn giản là phải kiểm tra xem phiên bản pdf của tài liệu có cũ hơn phiên bản tex của tài liệu hay không. Đây là một đơn giản  Makefile sẽ chỉ xử lý một tài liệu LaTeX.

TEXFILE= paper
$(TEXFILE).pdf: $(TEXFILE).tex
	latexmk -pdf -quiet $(TEXFILE)

Dòng đầu tiên chỉ định tên tệp của tôi, trong trường hợp này  paper.tex. Dòng thứ hai chỉ định rằng tệp pdf phải được tạo từ tệp tex và dòng cuối cùng giải thích cách thực hiện điều đó. Người dùng MikTeX có thể thích  pdftexify thay vì  latexmk.

Để sử dụng ở trên  Makefile, sao chép mã vào một tệp văn bản đơn giản được gọi  Makefile và lưu trữ nó trong cùng thư mục với tệp tex của bạn. Thay đổi dòng đầu tiên để tên của tệp tex của bạn (không có phần mở rộng) được sử dụng. Sau đó nhập  make từ một dấu nhắc lệnh trong cùng thư mục với tệp tex và nó sẽ làm bất cứ điều gì cần thiết để chuyển đổi tex của bạn sang pdf.

Tất nhiên, thông thường bạn sẽ không bận tâm với  Makefile nếu đó là tất cả những gì nó đã làm. Nhưng ném vào rất nhiều tệp R, và nó trở nên rất đáng giá.

Makefile cho R và LaTeX

Chúng tôi cần một cách để cho phép  make có thể biết nếu một tệp R đã được chạy. Nếu các tệp R được chạy bằng

R CMD BATCH file.R

sau đó đầu ra được lưu dưới dạng  file.Rout. Sau đó  make chỉ phải kiểm tra nếu  file.Rout già hơn  file.R.

Tôi cũng muốn loại bỏ tất cả khoảng trắng từ các số liệu pdf được tạo trong R trước khi tôi đặt chúng vào tài liệu LaTeX. Có một lệnh tốt  pdfcrop mà làm điều đó. (Bạn nên có nó trên máy Mac hoặc Linux và trên Windows với điều kiện bạn đang sử dụng MikTeX.) Vì vậy, tôi cũng muốn tôi  Makefile cắt tất cả các hình ảnh nếu chúng chưa được thực hiện. Khi một hình ảnh được cắt, một tệp trống của biểu mẫu  file.pdfcropđược tạo để chỉ ra rằng nó  file.pdf đã bị cắt.

OK, bây giờ chúng tôi đã sẵn sàng cho điều kỳ diệu của tôi  Makefile.

# Usually, only these lines need changing
TEXFILE= paper
RDIR= .
FIGDIR= ./figs
 
# list R files
RFILES := $(wildcard $(RDIR)/*.R)
# pdf figures created by R
PDFFIGS := $(wildcard $(FIGDIR)/*.pdf)
# Indicator files to show R file has run
OUT_FILES:= $(RFILES:.R=.Rout)
# Indicator files to show pdfcrop has run
CROP_FILES:= $(PDFFIGS:.pdf=.pdfcrop)
 
all: $(TEXFILE).pdf $(OUT_FILES) $(CROP_FILES)
 
# May need to add something here if some R files depend on others.
 
# RUN EVERY R FILE
$(RDIR)/%.Rout: $(RDIR)/%.R $(RDIR)/functions.R
	R CMD BATCH $<
 
# CROP EVERY PDF FIG FILE
$(FIGDIR)/%.pdfcrop: $(FIGDIR)/%.pdf
	pdfcrop $< $< && touch $@
 
# Compile main tex file and show errors
$(TEXFILE).pdf: $(TEXFILE).tex $(OUT_FILES) $(CROP_FILES)
	latexmk -pdf -quiet $(TEXFILE)
 
# Run R files
R: $(OUT_FILES)
 
# View main tex file
view: $(TEXFILE).pdf
	evince $(TEXFILE).pdf &
 
# Clean up stray files
clean:
	rm -fv $(OUT_FILES) 
	rm -fv $(CROP_FILES)
	rm -fv *.aux *.log *.toc *.blg *.bbl *.synctex.gz
	rm -fv *.out *.bcf *blx.bib *.run.xml
	rm -fv *.fdb_latexmk *.fls
	rm -fv $(TEXFILE).pdf
 
.PHONY: all clean

Tải tập tin tại đây.  Đối với hầu hết các dự án tôi sao chép tệp này vào thư mục chính của dự án, sau đó tất cả những gì tôi phải làm là sửa đổi một vài dòng đầu tiên. RDIR chỉ định nơi lưu giữ các tệp R và  FIGDIR chỉ định nơi lưu giữ các số liệu. Thông thường tôi giữ những thứ này cùng nhau, nhưng đôi khi chúng có thể nằm trong các thư mục riêng biệt.

Bây giờ  make sẽ làm mọi thứ cần thiết - chạy các tệp R, cắt đồ họa pdf và xử lý tài liệu latex. Nhưng nó sẽ không làm bất kỳ bước nào không cần làm.

make R sẽ chỉ xử lý các tệp R.

make view sẽ chạy trình xem pdf, sau khi cập nhật tệp pdf nếu cần.

make clean sẽ xóa tất cả các tệp được tạo bởi latex hoặc bằng make, để toàn bộ quá trình phải được chạy lại ở make lệnh tiếp theo  .

Lưu ý rằng tất cả các tệp R của tôi phụ thuộc vào  functions.R. Đây là một tập tin có chứa các chức năng cụ thể của dự án. Nếu tệp này được cập nhật, tất cả các tệp R khác cũng sẽ cần cập nhật.

Đối với nhiều dự án, một số tệp R sẽ phụ thuộc vào một số tệp khác đã chạy. Ví dụ:  read.R có thể đọc dữ liệu và định dạng lại để phân tích, trong khi  plot.Rcó thể tạo ra một số biểu đồ giả định rằng nó  read.R đã chạy. Để đảm bảo  makebiết về sự phụ thuộc này, chúng ta cần thêm một dòng

$(RDIR)/plot.Rout: $(RDIR)/plot.R $(RDIR)/functions.R $(RDIR)/read.R
	R CMD BATCH $<

Điều này nên được chèn vào nơi tôi có nhận xét # May need to add something here if some R files depend on others.

Điều này  Makefile hoạt động trên Linux. Người dùng Mac và Windows sẽ cần thay thế  evincebằng bất kỳ trình xem pdf nào họ thích.

Hữu ích 7 Chia sẻ Viết bình luận 0
Đã xem 4266