
우리는 종종 다음과 같은 상황에 처해 있습니다.계산잔뜩 뱉어낸다결과 값. 리소스 집약적인 계산을 수행하는 Python이나 스크립트 또는 R 스크립트를 상상해 보세요. 그런 다음 결과를 설명하고 텍스트나 표에 결과 값을 나열하려는 기사나 보고서를 작성합니다. 값을 복사하여 붙여넣는 것은 오류가 발생하기 쉽고 작업량이 많기 때문에 다음을 수행하는 것이 좋습니다.자동으로 값을 포함.
예:여기에 있는 모든 숫자 값은 스크립트의 결과이며 어떤 방식으로든 기사에 포함되어야 합니다.
이를 달성하는 가장 좋은 방법은 무엇입니까?
메모:계산은 여러 시간 동안 실행될 수 있으며 별도의 계산 클러스터에서도 가능합니다. 따라서 결과를 계산하는 것은 LaTeX 문서에 결과를 포함하고 컴파일하는 것과 얽혀 있지 않은 단계여야 합니다.
보너스 요구사항:include 명령뿐만 아니라 Latex 편집기(예: Overleaf)에 표시된 값을 보는 것이 좋을 수도 있습니다. 이는 Overleaf에 있는 것과 같은 Wysiwyg 편집기를 사용할 때 매우 도움이 될 수 있지만 값을 복사하여 붙여넣거나 Latex 파일을 전처리하지 않고도 이 작업을 수행할 수 있을지 의심됩니다.
또한보십시오:레딧에 올라온 이 질문.
답변1
결과를 별도의 텍스트 파일에 작성하여 사용\input
가장 간단하고 간단한 해결책은 계산 중에 각 값을 텍스트 파일에 쓰는 것입니다. 예를 들어, 계산은 마지막에 LaTeX 문서에 필요한 모든 값을 수집하고 텍스트 파일에 시간을 기록할 수 있습니다.
def write_include_value(name, value):
"""Write a value to a text file for later use in a LaTeX document.
Parameters
----------
name : str
name of the file, also used in the LaTeX document as name
value : str
the value to be stored, passed as string so formatting (e.g. number of
digits) needs to be done before calling the function
"""
with open(OUTPUT_DIR / "include-values" / name, "w") as f:
f.write(value + "\n")
함수를 호출할 때 표시되는 자릿수를 구성할 수 있습니다.
write_include_value("average_temperature", f"{average_temperature.values:.1f}")
LaTeX 문서의 서문에 다음 코드 조각을 넣으면 텍스트에 값을 쉽게 포함할 수 있습니다.
\newcommand*{\includevalue}[1]{\input{../../data/output/include-values/#1}\unskip}
그런 다음 새 명령을 사용하여 값을 사용할 수 있습니다 \includevalue
. 예를 들면 다음과 같습니다.
\includevalue{average_temperature}
함정과 단점
- siunitx 패키지는 highlevel 명령과 함께 작동하지 않으므로
\input
명령\includevalue
내부에서 사용할 수 없습니다\qty
. 따라서 단위가 있는 수량에 대한 추가 명령을 추가했습니다.
% The package siunitx does not work with the highlevel command \input, therefore \includevalue
% cannot be used inside of a \qty command. Instead use: \qtyincludevalue{filename}{m/s^2}
% Copied and adapted from here: https://tex.stackexchange.com/a/108093/8964
\def\inputval{0}
\newread\inputFile
\newcommand*{\qtyincludevalue}[3][]{%
\IfFileExists{../../data/output/data-values/#2}{
\openin\inputFile=../../data/output/data-values/#2
\read\inputFile to \inputval
\closein\inputFile
\qty[#1]{\inputval}{#3}%
}{\qty[#1]{#2}{#3}}%
}
- 일부 저널에서는 투고 과정에서 파일 수를 제한합니다. 별도의 파일을 통해 값을 포함하는 이 방법을 사용하면 쉽게 100개의 파일을 끝낼 수 있으며 제출 포털에서는 기사 제출을 허용하지 않습니다. 모든 포함 내용을 실제 값으로 바꾸는 해결 방법으로 이 Python 스크립트를 사용했습니다. LaTeX 문서 컴파일에 추가 단계를 추가하기 때문에 좋지 않습니다. 이로 인해 오류가 발생하기 쉽지만 작동합니다.
import os
import re
import sys
def replace_placeholders(filename):
with open(filename, "r") as f:
contents = f.read()
pattern = r"\\(qty)?includevalue\{([\w-]+)\}"
matches = re.findall(pattern, contents)
for match in matches:
replace_string = ""
file_path = os.path.join("data", "output", "data-values", match[1])
with open(file_path, "r") as f:
replace_string = f.read().strip()
if match[0] == "qty":
replace_string = "\\qty{" + replace_string + "}"
contents = contents.replace(
"\\{}includevalue{{{}}}".format(match[0], match[1]), replace_string
)
return contents
if __name__ == "__main__":
print(replace_placeholders(f"{sys.argv[1]}.noreplace"))
- 포함 값 파일이 있는 폴더의 경로는 Python 코드에서 한 번, LaTeX 헤더에서 다시 한 번 지정해야 합니다.
답변2
R을 사용한다면 Knitr를 사용하세요
니트LaTeX 문서에서 R 코드 조각을 실행할 수 있습니다. 계산 결과를 파일(NetCDF와 같은 이진 파일 또는 CSV 파일일 수도 있음)에 저장하는 경우 Knitr 및 R 코드를 사용하여 필요한 값을 로드하고 이를 LaTeX 파일에 포함할 수 있습니다.
<<results="asis",echo=FALSE>>=
cat(read.csv("a_csv_file.csv", sep=";")[1,2])
@
또는 테이블:
<<xtable, results="asis">>=
n <- 100
x <- rnorm(n)
y <- 2*x + rnorm(n)
out <- lm(y ~ x)
library(xtable)
xtable(summary(out)$coef, digits=c(0, 2, 2, 1, 2))
@
(다음에서 가져온 예칼 브로만)
이론적으로 Knitr은 Python도 지원하지만 R을 사용하여 LaTeX 내에서 Python 조각을 실행하는 것이 이상하다고 느낍니다. 따라서 R을 사용하지 않는다면 Knitr를 사용하지 말라고 권하고 싶습니다.
최소한의 예
\documentclass{article}
\begin{document}
The meaning is:
<<results="asis",echo=FALSE>>=
cat(read.csv("a_csv_file.csv", sep=";")[1,2])
@
\section*{A table}
<<xtable, results="asis",echo=FALSE>>=
n <- 100
x <- rnorm(n)
y <- 2*x + rnorm(n)
out <- lm(y ~ x)
library(xtable)
xtable(summary(out)$coef, digits=c(0, 2, 2, 1, 2))
@
\end{document}
위의 코드는 다음과 같이 저장되며 다음 knitr_test.Rnw
을 사용하여 tex 파일이 생성됩니다.
R -e 'library(knitr);knit("knitr_test.Rnw")'
tex 파일은 다음과 같습니다.
\documentclass{article}
% knitr inserts a lot of stuff in the header, omitted here for simplicity
\begin{document}
The meaning is:
42
\section*{A table}
% latex table generated in R 4.3.2 by xtable 1.8-4 package
% Wed Jan 17 17:53:32 2024
\begin{table}[ht]
\centering
\begin{tabular}{rrrrr}
\hline
& Estimate & Std. Error & t value & Pr($>$$|$t$|$) \\
\hline
(Intercept) & 0.24 & 0.08 & 2.8 & 0.01 \\
x & 2.02 & 0.09 & 21.3 & 0.00 \\
\hline
\end{tabular}
\end{table}
\end{document}
렌더링된 결과는 다음과 같습니다.
뒷면
온라인 LaTeX뒷면지원하다즉시 사용 가능한 Knitr. LaTeX 파일의 이름을 *.Rtex
.
불행히도 구문 검사는 Knitr 구문을 지원하지 않는 것 같습니다.
단점
- LaTeX 파일을 컴파일하는 동안 추가 단계가 필요합니다.
- 단일 값을 포함하는 코드는 꽤 깁니다.
더 많은 리소스
여기 훌륭하고 짧은 튜토리얼이 있습니다.LaTeX와 함께 Knitr을 사용하는 방법에 대해 알아보세요.
Knitr에 대한 좋은 개요는 다음에서 확인할 수 있습니다.뒷면의 문서.
이것Q&Acat()
출력 접두사를 숨기는 데 필요한 사용을 피하는 방법에 대해 설명합니다 [1]
.
답변3
당신은 다음의 개념을 검색하고 있습니다.프로그래밍을 읽고 쓸 줄 아는, 이는 실제로 R trough knitr를 사용하는 LaTeX에만 국한되지 않지만 아마도 지난 몇 년 동안 가장 성공적인 개념 증명이었을 것입니다.
그러나 R이나 Python, LateX에 국한되지 않는 일반적인 읽고 쓸 수 있는 프로그래밍의 경우 다음을 제안합니다.콰르토. Quarto는 Python, R, Julia 및 Observable을 사용하여 동적 콘텐츠를 생성하여 LaTeX 또는 ConTeXt(및 기타 여러 형식)를 통해 PDF를 생성할 수 있지만 여기서는 주제에서 벗어납니다...
R 청크가 있지만 Jupyter가 실행 코드가 다른 언어(python, julia, bash 등)인 경우 Quarto는 기본적으로 Knitr 엔진을 사용합니다. 보다여기 엔진 선택에 대한 자세한 내용을 확인하세요.
마지막으로 Knitr은 Python과다른 많은 언어, "이론적으로"뿐만 아니라. Python이 작동하는 동안 R을 통해 Python을 실행하는 것은 치명적인 죄가 아닙니다. 또한 동일한 문서에서 두 언어의 스니펫 실행을 허용하고 한 언어에서 다른 언어로 변수를 전달할 수도 있으므로 몇 가지 이점이 있을 수 있습니다. 예:
---
title : A minimal working example
format: pdf
classoption: twocolumn
header-includes: \columnsep1.5cm
---
```{r}
#| echo: false
library(reticulate)
```
##### This is Python in \LaTeX:
```{python}
#| echo: false
#| results: asis
import matplotlib.pyplot
import pylab
lst = [11.21,22.84,33.25,44.67,55.35]
lst2 = [5,6,7,12,24]
print("This is a plot of list")
print(lst)
print("and")
print(lst2)
print(":")
```
```{python}
#| echo: false
#| fig-cap: Pyhon plot
matplotlib.pyplot.scatter(lst,lst2)
```
\newpage
##### And this R using Python code
The values of python list "`lst`" are
`r knitr::combine_words(py$lst)` with a mean
of rougly `r round(mean(py$lst),1)`.
```{r}
#| echo: false
#| results: asis
#| fig.cap: R plot of Python lists
#| fig-height: 4
plot(py$lst,py$lst2,ylab="",
xlab="",col="blue",pch=19)
```
knitr의 사용을 피하기 위해 헤더에 추가하거나 engine: jupyter
(R 코드는 표시만 되고 실행되지는 않음) 간단히 마지막 부분을 제거하여 \newpage
R이나 knitr 없이 python3을 실행하는 Jupyter로 자동 전환할 수 있습니다.
하지만 어떤 이유로든 이 워크플로가 귀찮다면 다음도 있습니다.Python을 실행하기 위한 LaTeX 패키지곧장.
답변4
Latex 결과에 대한 새로운 Latex 명령 생성
자신만의 Latex 명령을 만들 수 있습니다. 즉, 각 결과에 대해 하나의 명령을 생성할 수 있습니다. 계산 파이프라인은 명령 정의 및 결과를 포함하는 Latex 헤더 파일을 생성하는 스크립트를 실행할 수 있습니다. 그러면 이 파일이 Latex 문서에 포함될 수 있습니다.
이는 다음과 다소 유사합니다.텍스트 파일을 통한 솔루션 및\input
. 댓글에서 이 변형 솔루션을 제안한 @Teepeemm에게 감사드립니다.
코드 조각 1
계산 파이프 라인에 다음과 같은 것을 추가하고 Latex 문서에 필요한 사전에 모든 값을 추가하십시오.
LATEX_FILE_NAME = 'result_values.tex'
result_values = {}
meaning_of_life = 42
result_values["meaningoflife"] = f"{meaning_of_life:d}"
# - A unit can be passed as string as second parameter: the LaTeX package siunitx will be used to display the quantity.
# - Use .2f for rounding to two decimals.
gravity_ms2 = 9.80665
result_values["gravity"] = f"{gravity_ms2:.2f}", "m/s^2"
write_result_values(result_values, LATEX_FILE_NAME)
코드 조각 2
이 함수는 Latex 헤더를 작성합니다.
import re
def format_latex_command(key, value, unit=None):
# test if key contains invalid characters for a latex command:
if not re.match(r"^[a-zA-Z]+$", key):
raise ValueError(f"Invalid key '{key}': not a valid latex command name")
if unit is not None:
value = f"\\qty{{{value}}}{{{unit}}}"
return f"\\newcommand{{\\{key}}}{{{value}}}"
def write_result_values(result_values, filename):
"""Write the result values to a latex header file creating new Latex command for each value.
Parameters
----------
result_values : dict
Results to be written to the Latex header file: keys of the dictionary are the names of the
latex commands the values are either a single value or a tuple containing the value and the
unit.
filename : str
The name of the Latex header file to write the result values to.
"""
result_values_flat = [
(key, *value) if isinstance(value, tuple) else (key, value)
for key, value in result_values.items()
]
latex_commands = [format_latex_command(*params) for params in result_values_flat]
with open(filename, "w") as f:
f.write("\n".join(latex_commands) + "\n")
Latex 문서에서 사용하는 방법
위의 코드 조각 1을 실행하면 파일이 result_values.tex
생성됩니다.
\newcommand{\meaningoflife}{42}
\newcommand{\gravity}{\qty{9.81}{m/s^2}}
...그런 다음 새로운 Latex 명령을 사용하여 텍스트에 값을 추가할 수 있습니다.
\documentclass{article}
\usepackage{siunitx}
\include{result_values}
\begin{document}
\section*{Example of including result values}
The gravity constant is \gravity. And the meaning of life is \meaningoflife.
\end{document}
렌더링된 결과는 다음과 같습니다.