
背景
こんにちは。皆さんのご意見をお待ちしております。とても長い投稿で申し訳ありませんが、ほとんどの新規ユーザーは十分な背景情報を共有していないと非難されていることに気づきました。TLDRバージョンは、etoolsからのブール式内でpgfplottableで読み込んだセル値を使用する方法がわかりません。。
私は、csv から読み込まれた値に基づいて、特定のテキスト部分をフォーマットするのに苦労しています。毎年、ほぼ同じアウトラインで、特定の場所で毎年異なる値を持つドキュメントを作成する必要があります。たとえば、2015 年のドキュメントには次のように記載される可能性があります。
2015年の米国の総定格容量は 1,159,748 MW。
しかし、2016 年には、この文は次のように更新されるはずです。
2015年の米国の総定格容量は 1,174,115 MW。
私たちはこれを Python + LaTeX を使用したより効率的なプロセスに移行しようとしています。実際のデータ/図は Python で csv に保存され、LaTeX でそれらの csv を読み込んでドキュメントが自動更新されます。つまり、1 つのコマンドライン スクリプトですべてのドキュメントを再作成できるということです。
これまでのところ、この答えの助けを借りて実際に csv を読み込んで LaTeX にインラインで印刷しても問題はありません。MWE:
\documentclass[16pt]{article}
\usepackage{pgfplotstable, pgfplots, etoolbox, xcolor}
\pgfplotstableread[col sep=comma]{data_values_test.csv}\sectionIIvars
\def\getcell#1#2#3{
\pgfplotstablegetelem{#1}{#2}\of{#3}\pgfplotsretval%
}
\begin{document}
Renewable electricity in was \textbf{\getcell{8}{all_re}{\sectionIIvars}\% of total installed electricity capacity and \getcell{3}{all_re}\sectionIIvars}\% of total annual generation in the United States}.
\end{document}
結果は次のようになります:
実際の csv を皆さんと共有する方法はわかりますが、それは非常に簡単です。1 行目はヘッダー/名前です (たとえば、コードから「all_re」というタイトルの列があることがわかります)。最初の列は、どの行がどの変数に対応するかを追跡するのに役立つ名前 (文字列) です。csv の残りの部分は数字だけです。'\getcell{8}{all_re}{\sectionIIvars}' 関数を使用すると、定義済みテーブル '\sectionIIvars' から行 8、列 'all_re' のセルの内容にアクセスできます。
問題
ここでの LaTeX 出力は、それを「出版準備完了」にするチームに渡されます。図は最終出版まで絶えず更新されるため、このチームにドキュメントの複数の反復を渡す必要があることがよくあります。この外部チームが「出版準備完了」の下書きを更新するために必要な時間を短縮するために、反復間で変更された値を自動的にフォーマットできるようにする必要があります。たとえば、上記のコード スニペットの 2 番目の値が反復間で 15.55 から 17.56 に変更された場合、その 17.56 を赤で表示する必要があります。'.tex' ファイル内のコードが変更されていない場合でも、基礎となる csv のみが変更されます。以下を参照してください。
残念ながら、これを動作させることができません。いくつか試してみましたが、効果はありませんでした。
ラテックスディフ
私が知る限り、これは '.tex' ファイル自体の変更のみをキャプチャするため、すぐにこれを除外しました。実際の .tex ファイルはここでは変更されないため、役に立ちません。
ifboolexpr
私の時間のほとんどはここで過ごしました。これはすべて、書かれたコマンドに基づいていますこの回答ではそれぞれのケースで、私はブール関数を使って、ある csv の回答を別の csv の回答と比較しようとしています。そのアイデアは、Python スクリプトが反復処理間で '\sectionIIvars' テーブル内の回答を比較し、実際の回答が 2 番目の csv ('\booltestsecII' と呼ぶことにします) に変更されたかどうかを書き込むことができるというものです。その後、Latex は '\sectionIIvars' 内の回答を印刷できます。ただし、'\booltestsecII'に基づいてフォーマットします. '\booltestsecII' は '\sectionIIvars' と同じサイズと形状になりますが、0 と 1 (それぞれ '変更なし' と '変更されました!') のみになります。
試行 1
まず、getcell 関数を書き直して追加の引数を取り、'\sectionIIvars' と \booltestsecII' の間で同じ行とセルを比較するようにしました。
\documentclass[16pt]{article}
\usepackage{pgfplotstable, pgfplots, etoolbox, xcolor}
\pgfplotstableread[col sep=comma]{data_values_test.csv}\sectionIIvars
\pgfplotstableread[col sep=comma]{Boolean_change_test.csv}\booltestsecII
\newcommand{\getcell}[4]{
\ifboolexpr{ test {\ifnumcomp{\pgfplotstablegetelem{#1}{#2}\of{#4}\pgfplotsretval}{=}{1}}}
{\pgfplotstablegetelem{#1}{#2}\of{#3}\pgfplotsretval}
{\textcolor{red}{\pgfplotstablegetelem{#1}{#2}\of{#3}\pgfplotsretval}}
}
\begin{document}
Renewable electricity in was \textbf{\getcell{8}{all_re}{\sectionIIvars}{\booltestsecII}\% of total installed electricity capacity and \getcell{3}{all_re}{\sectionIIvars}{\booltestsecII}\% of total annual generation in the United States}.
\end{document}
これにより、必要な入力をすべて指定したつもりだったにもかかわらず、「! 数値が不足しているため、ゼロとして扱われます。」というエラー (必要な関数入力が不足していることを示す傾向がある) が発生しました。続行しようとすると、「\ifnum に = が挿入されていません。」というエラーが発生します。もう一度続行しようとすると、「! 水平モードでは `\numexpr' は使用できません。」というエラーが発生します。
試行2
これはおそらくネストされたマクロと関係があるのではないかと考え、関数定義を次のように変更してみました(この質問に基づいて):
\newcommand{\getcell}[4]{
\ifboolexpr{ test {\ifnumcomp{\pgfplotstablegetelem{##1}{##2}\of{##4}\pgfplotsretval}{=}{1}}}
{\pgfplotstablegetelem{##1}{##2}\of{##3}\pgfplotsretval}
{\textcolor{red}{\pgfplotstablegetelem{##1}{##2}\of{##4}\pgfplotsretval}}
}
しかし、同じエラーが発生しました。
試み3
少し単純化して、csv から値を読み取り、それを 'ifboolexpr' を使用して数値と比較することに焦点を当てようとしましたが、それでもうまくいきませんでした。
\documentclass[16pt]{article}
\usepackage{pgfplotstable, pgfplots, etoolbox, xcolor}
\pgfplotstableread[col sep=comma]{Boolean_change_test.csv}\booltestsecII
\newcommand{\checkchangesecII}[3]{
\ifboolexpr{ test {\value{\pgfplotstablegetelem{#1}{#2}\of{#3}\pgfplotsretval}{=}{1}}}
{do this}
{\textcolor{red}{do that}}
}
\begin{document}
\checkchangesecII{0}{solar}{\booltestsecII}
\end{document}
これにより、「! Missing \endcsname insert.」エラーが発生し、次に「! Extra \endcsname.」エラーが発生し、最後に「1=1do that」が出力されます。
まとめ
今のところ、何も解決していませんが、誰かの理論を聞くのにとても興味があります。LaTeX は数値を読み込んでいるものの、数値として認識していないため、「数値 1」と「文字列 1」を比較できないのではないかと思います。これを確認または修正する方法がわからないため、ここに書いています。
あらゆるフィードバックをありがとうございます。質問の形式が適切でない場合は申し訳ありませんが、お知らせください。できる限り編集します。
答え1
かなり近かったですよ:
1回目の試行では、
\ifboolexpr{ test {\ifnumcomp{\pgfplotstablegetelem{#1}{#2}\of{#4}\pgfplotsretval}{=}{1}}}
ここでまたはを に\pgfplotstablegetelem{#1}{#2}\of{#4}
割り当て、その後 を使用します。なぜこれが必要なのでしょうか。 が直接戻り値を与えないのはなぜでしょうか。問題は、 で必要な割り当てやその他の操作などの一部の操作が「拡張可能」ではないことです。つまり、基本的には実行できますが、値が要求される場所には置けません。したがって、テストする値が期待される の内部を使用しても機能しません。ここで が役立ちます。テストの前に移動し、内部でのみ拡張可能を使用できます。1
0
\pgfplotsretval
\pgfplotsretval
\pgfplotstablegetelem{#1}{#2}\of{#4}
\pgfplotstablegetelem
\pgfplotstablegetelem
\test
\pgfplotsretval
\pgfplotstablegetelem
\pgfplotsretval
\documentclass[16pt]{article}
\usepackage{pgfplotstable, pgfplots, etoolbox, xcolor}
\pgfplotstableread[col sep=comma]{data_values_test.csv}\sectionIIvars
\pgfplotstableread[col sep=comma]{Boolean_change_test.csv}\booltestsecII
\newcommand{\getcell}[4]{
\pgfplotstablegetelem{#1}{#2}\of{#4}
\ifboolexpr{ test {\ifnumcomp{\pgfplotsretval}{=}{1}}}
{\pgfplotstablegetelem{#1}{#2}\of{#3}\pgfplotsretval}
{\textcolor{red}{\pgfplotstablegetelem{#1}{#2}\of{#3}\pgfplotsretval}}
}
\begin{document}
Renewable electricity in was \textbf{\getcell{8}{all_re}{\sectionIIvars}{\booltestsecII}\% of total installed electricity capacity and \getcell{3}{all_re}{\sectionIIvars}{\booltestsecII}\% of total annual generation in the United States}.
\end{document}