表の中身が .csv ファイルなど 外部データ として既にあるなら、セルを一つずつ手で打ち込む必要はありません。LaTeX には CSV を読み込んで表に変換するパッケージがいくつもあり、データが変わってもソースを書き直さずに済みます。このページでは、手早い **csvsimple、整形に強い pgfplotstable、データベース的に扱う datatool の三つを使い分けとともに紹介し、最後に、数値を 小数点でそろえる** siunitx の S 列に触れます(S 列の詳細は「単位(siunitx)」のページに譲ります)。
なぜデータから表を組むのか
実験結果や集計表は、表計算ソフトや測定機器から CSV(カンマ区切りの値) として出てくることがほとんどです。これを tabular のセルへ手作業で写すのは、退屈なうえに間違いのもと——データが一行増えるたび、桁が一つ変わるたびに、原稿に手を入れることになります。
考え方を変えて、データはデータファイルに置いたまま、LaTeX には「読み込んで組め」とだけ指示する ことができます。こうすれば、データを更新して再コンパイルするだけで表が追従します。元の CSV が一つあれば、本文・スライド・付録で同じ数値を何度でも使い回せ、転記ミスも起きません。この「データと体裁の分離」は、論理構造と見た目を分ける LaTeX の発想と地続きです。
このページの例では、次の小さな CSV ファイルを使います。一行目は 見出し行(ヘッダ) で、product・price・weight という列名が並び、二行目以降が中身です。
product,price,weight
Apple,380,182.5
Orange,120,95.0
Melon,1280,1450.2手早く読む — `csvsimple`
csvsimple は、CSV を読み込んで表や繰り返しを作る、軽快なパッケージです。\usepackage{csvsimple} で読み込みます(現行版は内部で LaTeX3 実装の csvsimple-l3 を選びます)。まず最も手軽なのが **\csvautotabular{data.csv}**。ファイル名を渡すだけで、CSV 全体を自動的に tabular に流し込み、一行目を見出しとして罫線つきで組んでくれます。中身をざっと表にしたいときに向きます。
\csvautotabular{data.csv}この一行で、product・price・weight を見出しとする 3 列・3 行の表ができます。手軽な反面、整形の自由度は限られます。**列の揃え方や罫線、列の取捨選択まで自分で決めたいなら \csvreader を使う** ——これが csvsimple の本命です。
\csvreader は三つの引数を取ります。\csvreader[オプション]{data.csv}{割り当て}{本体} の形です。第二引数 が読み込むファイル、第三引数 が「列名をマクロに結びつける割り当て」、第四引数 が「各行で出力する内容」。たとえば price=\price と書けば、見出し price の列の値が、本体の中で \price として使えるようになります。表の枠組みは tabular= や table head=(見出し行)といったオプションで与えます。
\csvreader[
tabular = l r r,
table head = \hline Product & Price & Weight \\ \hline,
late after line = \\]
{data.csv}
{product=\product, price=\price, weight=\weight}
{\product & \price & \weight}ここでは tabular = l r r で「左・右・右」の 3 列を宣言し、table head で見出し行と上の罫線を置き、本体 {\product & \price & \weight} が各データ行をセルに展開します。late after line = \\ は **各行の後に行末 \\ を補う** 指定です(行と行のあいだにだけ改行を入れ、最終行のあとには余計な改行を残さないための定石)。見出し名にスペースや記号が含まれる場合は、第三引数で番号を使う流儀もあり、\csvcoli・\csvcolii・\csvcoliii … が 1 列目・2 列目・3 列目 の中身を表します。
既定では一行目は 見出し として扱われ、データには含まれません。見出し行のない CSV を読むときは、星付きの \csvreader* を使うと一行目もデータ行として読まれます。csvsimple は他にも、条件で行を絞る filter、定義済みの割り当てを使い回す \csvstyle/\csvnames など、表以外の繰り返し処理にも使える機能を備えています。
整形して読む — `pgfplotstable`
数値の 見せ方 まで作り込みたいなら、pgfplotstable が最も強力です。pgfplots の一部で、\usepackage{pgfplotstable} で読み込みます。中心となる命令は **\pgfplotstabletypeset[オプション]{data.csv}** ひとつ。これが CSV を読み、指定した桁数・数値形式に整え、内部で tabular を組み立てて出力します。CSV を読むときは区切り文字を col sep=comma で伝えます。
ふるまいは、すべて キー=値のオプション で制御します。代表的なものを挙げます。
| オプション | 働き | |
|---|---|---|
col sep=comma | col sep=comma | CSV(カンマ区切り)として読む。既定は空白区切り |
header | header=has colnames / header=false | 一行目を列名として扱う / 見出しなしとして扱う |
columns | columns={a,b,...} | 出力する列とその順序を選ぶ |
columns/NAME/.style | columns/price/.style={...} | 特定の列だけに書式を与える |
column name | column name=見出し | その列の見出し文字列を差し替える |
fixed | fixed, fixed zerofill, precision=n | 固定小数点・末尾ゼロ詰め・小数桁数 n |
sci | sci, sci zerofill | 科学表記(指数形式)で組む |
string type | string type | 文字列の列(数値整形をしない) |
dec sep align | dec sep align | 列を小数点でそろえる(array が必要) |
\pgfplotstabletypeset[
col sep = comma,
header = has colnames,
columns = {product, price, weight},
columns/product/.style = {string type, column name = Product},
columns/price/.style = {column name = Price, fixed, precision = 0},
columns/weight/.style = {column name = Weight (g), fixed, fixed zerofill,
precision = 1, dec sep align},
]{data.csv}この例では、product 列を string type(文字列)として、price 列を整数(precision=0)として、weight 列を小数 1 桁・末尾ゼロ詰めで組み、dec sep align で小数点をそろえています。見出しは column name でそれぞれ差し替えました。同じデータでも、precision を変えるだけで桁数が変わる ——数値の体裁を CSV と切り離して制御できるのが pgfplotstable の強みです。
さらに pgfplotstable は、読み込んだ列から 計算列 を作れます。create on use で「使うときに計算する列」を定義したり、columns/.../.style のなかで後処理(postproc cell content)を施したりと、表計算ソフトに近いことが LaTeX 内で完結します。罫線まわりは every head row/.style や booktabs 連携(\toprule/\midrule/\bottomrule を自動で入れる設定)で整えられます。ここまで作り込めるぶん記法は重く、**「凝った数値表」には pgfplotstable、「素朴な CSV → 表」には csvsimple** という住み分けが目安です。
データベースとして扱う — `datatool`
三つめの datatool は、CSV を データベース として読み込み、行ごとの繰り返し処理(差し込み印刷のような処理)を得意とします。\usepackage{datatool} で読み込み、まず \DTLloaddb{名前}{data.csv} で CSV を名前付きのデータベースに取り込みます。既定では一行目が見出しとなり、その列名が各値の キー になります。見出しのない CSV は \DTLloaddb[noheader]{...}{...} とすると、列が Column1・Column2 … と自動命名されます。
読み込んだら、**\DTLforeach{名前}{割り当て}{本体}** で各行を順に処理します。割り当ては \DTLforeach{db}{\Product=product,\Price=price}{…} のように「マクロ=列名」で書き、本体のなかで \Product・\Price がその行の値に展開されます。表にするときは、tabular の中で \DTLforeach を回し、本体の末尾に行末 \\ を置きます。
\DTLloaddb{goods}{data.csv}
\begin{tabular}{l r}
\hline
Product & Price \\
\hline
\DTLforeach{goods}{\Product=product, \Price=price}{%
\Product & \Price \\}
\hline
\end{tabular}この例では goods という名前で CSV を読み込み、tabular の中で \DTLforeach が行ごとに「商品名 & 価格」を出力します。datatool の真価は単なる表組みより データ操作 にあります——数値の合計・平均、並べ替え、条件による行の除外などをマクロで行え、文献リストや差し込み文書の生成にも使われます。逆に、ただ CSV を表にするだけなら csvsimple のほうが簡潔です。
数値を小数点でそろえる — siunitx の `S` 列
データの出どころが CSV であってもなくても、数値を並べた列は 桁をそろえないと読みにくい という問題は共通です。手で打った tabular でこれを解決する定番が、siunitx の **S 列** です。列指定で r などの代わりに S と書くと、その列の数値が 小数点の位置で整列 します。\usepackage{siunitx} を読み込めば使えます。
\begin{tabular}{l S[table-format=4.1]}
\toprule
{Product} & {Weight / \unit{\gram}} \\
\midrule
Apple & 182.5 \\
Orange & 95.0 \\
Melon & 1450.2 \\
\bottomrule
\end{tabular}この例では、2 列目を S[table-format=4.1] として「整数 4 桁・小数 1 桁」で組み、182.5・95.0・1450.2 を小数点でそろえています。二つの要点 があります。一つは table-format=整数桁.小数桁 を 列中で最も大きな値に合わせて 指定すること。もう一つは、**列見出しのような文字列は波括弧 {…} で囲んで保護** することです({Weight / \unit{\gram}})。保護を忘れると siunitx が見出しを数値として解釈しようとし、整列が崩れます。
S 列の詳しい使い方——table-format の指定、文字列の保護、\multicolumn 内で使えるマクロ版 \tablenum、指数つきの値の扱いなど——は「単位(siunitx)」のページで扱っています。本文の量は \qty、表の中の数値は S 列、と役割を分けると、文書全体で数値表記が一貫します。
どれを使うか
目的に応じて使い分けるのが一番です。おおよその指針は次のとおり。
- 素朴な CSV → 表 なら
csvsimple。\csvautotabularで即席、\csvreaderで列の揃えや罫線まで制御。 - 数値の桁数・形式を作り込む/計算列が要る なら
pgfplotstable。最も強力だが記法は重め。 - 集計・並べ替え・条件処理などデータ操作 が主目的なら
datatool。差し込み文書にも。 - 列内の数値を小数点でそろえたい だけなら
siunitxのS列。手書きのtabularにそのまま使える。
いずれの方法でも、土台になるのは tabular の列指定・&・\\・罫線という共通の約束ごとです。まず「tabular の基本」を押さえたうえで、データの量と整形の要求に合わせて道具を選ぶとよいでしょう。