library(ggplot2)
ggplot(airquality, aes(Temp, Ozone)) +
geom_point() +
geom_smooth(method = "loess", se = F, formula = y ~ x)
ggplot(mtcars, aes(x = factor(cyl), y = mpg)) + geom_boxplot()
セクション見出しへの相互参照も, 見出し側に {#sec-<ラベル名>}
のように指定すれば, セクション 2.4.1 というふうに参照できる.
相互参照に関する詳しい話は公式の Cross References のセクションを見てほしい.
Jupyter や VS Code への対応
私自身は Jupyter をあまり好まないが, これが利用者層を増やす可能性が一番ありそうな, 大きな特徴であるとも思う. Jupytyter(lab) は IDE としてもドキュメントエディタとしてみても機能がどっちつかずなので (この辺の不満を書いていたらとても長くなったので脚注にした), Jupyter にも knitr のチャンクオプションのような機能が用意され, 簡単にソースコードの表示を切り替えたりできないか, あるいは公式に互換性をサポートしてくれたら良いなと思いながら実現されないので私は Jupyter を使わない作業スタイルを追求し続けていたが, 先に Quarto がこれを実現することになりそうだ.
Quarto は Jupyter でも Rmarkdown のチャンクオプションと似た機能を提供するため, 実行オプション (Execution Options) という機能を用意している. これによって,
- 長大なコードを折りたたんで出力する (クリックで展開するアレ)
- 読み込みログや大して意味のない大量の警告メッセージ (しかし開発者にとっては一応確認する必要があるので消せない) を文書生成時に非表示にする
- 逆にコードの解説のため, コードのみの出力する
- 図表のキャプション表示と相互参照する
といったことが全てできるようになり, 整った文書を簡単に出力できるようになる. もちろん YAML メタデータも与えられるから, HTML や PDF 生成するときの全体的なスタイル変更も, 従来の Jupyter 側のエクスポート機能を使うよりかなり簡単だ.
具体的にはこのような使い方になる. セル内の冒頭に #|
の後に続けて書く記法で, HTML や PDF に変換したときの表示方法 (notebook 上での表示ではない) を制御することができる. 例えば以下の echo: false
はコードを表示しない, warning: false
は警告を表示しない, という意味である. グラフのみ掲載して共有したい場合などに便利だろう.
同様に, VS Code の Jupyter Notebook インターフェイス上でも Quarto を使用できるようだ. Google Colaboratory も ipynb 形式でファイルをダウンロードすればたぶん使えると思う (普段使わないので詳細は不明).
(実は先日公開した Pysocviz も, notebook で用例を作成した上で Quarto で PDFなどの静的なドキュメントに変換しようと考えていたが, 開発版で不安定なのでメンテが大変になるかもと思い直してやめたという経緯がある.)
多様な Jupyter カーネルへの対応
Jupyter への対応についてもう1つ強調すべきは, Quarto 文書ファイルの新規作成時の設定項目に Jupyter カーネルを指定する jupyter
という項目があること. 公式ドキュメントでは Python の例しかなかったが, このような項目があるということは, 公式ドキュメントには明記していないものの Quarto は Python 以外の Jupyter カーネルも対応している, あるいは将来そうする予定なのではないか, ということで Julia カーネルを指定してみたところ, HTML 版のみオプションも含め動作した. R Markdown では JuliaCall というパッケージを使い Julia コードのチャンクを書くことができるが, 現在はグラフの表示がうまくいかなかったりと制約が多い. しかし Quarto ではそのような問題は見られなかった.
Jupyter カーネルはかなりいろいろな言語に対応しているが, 実際にこのレポート作成などと相性がよさそうなのは R, Julia, Matlab, Octave あたりぐらいだと思うが後二者は持ってない & ほとんど使ってないので R と Julia の例のみ付録した.
なお, Julia 側のインターフェースも作ってるようだ (おそらく作りかけなので未検証): https://github.com/quarto-dev/quarto-julia
現時点での制約
現時点で気になった点・注意点を挙げていく. まだ開発版なのでおそらく今後どんどん不具合が修正され機能も追加されていくとは思うが.
- グラフィックデバイスの扱いが不明瞭. 日本語ユーザにとって現状これが一番ネックな気がする. 最近書いたように Windows や Mac でグラフに書いた日本語を文字化けさせないためには ragg パッケージのデバイス関数や
cairo_pdf
が使えるといいのだが, 指定方法がはっきり書かれていない. 現状は .qmd
ならば #| dev: cairo_pdf
のように書けば適用されるようだが, 一方で YAML メタデータの execute:
に書いても認識されないようだ (Quarto ではなく knitr の機能が適用されている?).
- YAML メタデータのブール値で
yes
/no
が使えない. true
/false
のみ
- R Markdown の出力フォーマット関数に対応するものがない
- 私が作った rmdja は出力フォーマット内で日本語文書用の独自テンプレートを呼び出したり, 設定を自動調整したりしていたが, それができなくなった. knitr のフックやフィルタで代用できそうなところもあるが, 複雑な処理を内部化し, ユーザがほとんど何も設定しなくてもいいようなテンプレートを用意するのは難しい
- Markdown や HTML に対応しているように見えて実は完全に互換性があるわけではなかったり独自仕様だったりするサービスは結構あるのでこれは少し困る
- Jupyter の変換も便利だがまだ足りない機能も多い
- たとえば Python で描いたグラフに対して相互参照やキャプションをつけることができるが,
kable()
のような表は作れない (Pandas の表示に対応していない)
- Julia は HTML ならおおむね問題なく動くが, PDF出力時の画像表示がやや使いづらい
qmd
を使用した場合は従来どおり JuliaCall が使われてしまう
Quarto の導入方法
Quarto の導入に特に難しいことはないが, 上記のように開発版であるため動作が不安定である可能性が高いことには注意してほしい. Quarto はすでに公式ドキュメントがある程度充実しており, インストール方法に関するページ も作られているので, ここでは多くを書かない. GitHub から Quarto CLI の最新のリリースをダウンロードする. .deb
, .pkg
, .msi
の3通りのバイナリ/インストーラが用意されているので, 主要な OS は簡単にインストールできる. Quarto CLI 単体だとターミナルでの呼び出しでしか使えないため, 「Pandoc の機能拡張版」というような認識で良いだろう. インストールできたら, RStudio を再起動すると新規作成ファイルの一覧に “Quarto Doc” が追加されているはずであるので選択する. R 側で操作するための quarto パッケージもインストールが必要である.
その他 TeX や Pandoc の設定が必要な場合もあるが, R Markdown を既に使っているならその設定を引き継げることが多いので説明は省略する. Jupyter 上で使いたい場合はもちろん Python や Jupyter が使えるようにする必要がある. これらの環境設定の多くはターミナルの quarto
コマンドで確認できる.
RStudio 上での使用法
今後変更される可能性が高いので, あまり細かいことは書かない.
RStudio 上で knitr/jupyter を使用する場合
RStudio で Quarto Doc を新規作成すると, 設定ウィンドウが開かれる. この設定は .Rmd
の YAML メタデータに対応する部分で, 後から書き換えることもできる. とりあえず エンジンが knitr になっていることだけ確認してほしい (図 5).
“Create” を押すと .qmd
ファイルが作られる. エディタ上での見た目は .Rmd
とそっくりそのままであり, YAML メタデータ + Markdown + knitr チャンクで構成される. 細かい構文の違いは既に書いたとおり. これも既に書いたがビジュアルエディタモードも使える.
R Markdown で “knit” ボタンだったものが “Render” に変わっており, これで qmd ファイルをコンパイルできる.
エンジンに Jupyter を選択した場合も, テンプレートのチャンクエンジンが Python になるだけでほぼ同じである. この場合は reticulate のインストールと設定が必要なことに注意.
(なお, 現時点では “Preview in Window” を選択してもなぜか Viewer ペーンに表示されてしまう. PDF の場合はこの手の組み込みビューアの例にもれず, 文字表示がちょくちょくおかしくなるので注意. PDF が正しく出力されないと慌てる前に Okular とか Sumatra とかで見たほうがいい.)
Jupyter 上で Python3 カーネルを使用する場合
公式ドキュメントの対応する箇所はこちら: https://quarto.org/docs/tools/jupyter-lab.html
Jupyter(lab) を起動した状態で, ターミナルで以下を実行する (JupyterHub を使ってリモートサーバ上で動かしている場合はもちろんホスト側のターミナルで)
quarto preview notebook.ipynb
これはリアルタイムプレビューで, notebook 側の変更がすぐに反映される. つまり R Notebook のような機能.
R Markdown の Knit ボタンのように文書を生成するには quarto render
コマンドを使う.
quarto render notebook.ipynb
format:
の形式が複数書かれている場合は1番上のものが適用されるので, 明示的に指定したい場合は, --to pdf
のようなオプションを追加する.
Jupyter は元から Markdown セルを使用できるため, Markdown セル内の記述が qmd/Rmd の地の文に対応する. 出力オプションも R の場合と同様に notebook のセル内に実行オプションを書くことで適用される.
R Markdown はデフォルトの設定では Knit 時に全てのチャンクを実行するが, .ipynb
ファイルに対して quarto render
を使っただけではセルが再実行されず, .ipynb
内部に保存されたものだけを反映する. 生成時に改めて実行するには --execute
オプションを追加する. 逆に言えば, 既存の .ipynb
ファイルを quarto render
で変換するだけなら Jupyter 本体は不要である.
また, quarto convert
コマンドで .ipynb
と .qmd
を相互に変換できるらしい (今回は試していないので詳しい挙動はわからない.).
Jupyter 上で Julia カーネルを使用する場合
公式ドキュメントには書かれていないが, Jupyter に Julia カーネルを登録すれば, 同じ要領で Julia のコードを埋め込んだ文書を作ることもできた. ただし, Julia の Plots や Gadfly はデフォルトでは SVG 形式で画像を出力するため, PDF での出力がうまくいかない. 今回はとりあえず PNG に変更して対処したが, Gadfly のみうまく動作していないようだ.
まとめ
Jupyter (Jupyerlab) は結構使われているが, 個人的には IDE としてもドキュメント作成ツールとしてもどっちつかずな感があった. それは既に述べたように, IDE としての機能が多くなく, 対話的処理であると便利な機能もほとんどない (Jupyter にはプラグインで一応あるが, lab にはまだ対応していない). 逆にドキュメント作成ツールとして見ると, 長大なコードを隠すことができず, 技術文書や論文等で必要なフォーマットに変換するのも大変である. 去年登場した Jupyter Book もオンラインドキュメントの作成には便利そうだが, R Markdown のようにいろいろな媒体への出力を想定していないようだった.
しかし, Quarto の変換機能を使えばドキュメント作成ツールとしての使い勝手はかなり改善されると思う. Jupyter はもともと Markdown に対応しており, また実行オプションや YAML メタデータの記述は既存の ipnynb ファイルの設定と競合することは少ないと思われるため, 気軽に試すことができる. もちろん, 既に書いたように細かい不具合や不満はあるが, それでも清書してない .ipynb
を共有するよりは見た目が良くなるのではないだろうか.
先日更新された knitr の新機能は, Quarto の新機能を狙ったものにみえる. RStudio 社としては, 今後積極的に Quarto をアップデートしていくのではないかと勝手に期待している.
つまり, おまえは万物を Quarto で書ける日が近いことが証明されたかたちだ. そして rmdja も来年くらいには不要になってそう
付録: 各種設定での出力例
- 冒頭に書いたようにこの投稿は Quarto で生成したものだが, R Markdown および Quarto の強みは同一のソースを少し設定を変えるだけで Markdown や HTML や PDF の文書で生成できる点にある. よって, この同一のファイルで作成した例を GitHub に投稿しておいた. ただし, DOCX (Word) や PPTX (パワーポイント) は確認がめんどくさいので Libre Office でざっと閲覧したのみで細かく確認してない. 興味のある人だけ各々確認してほしい.
まだ開発途上なので, 思ったよりうまく動作しない箇所も多い. ちょっと遠回りな方法で解決できそうなケースもあったが, 将来のアップデートで使いやすくなることを期待して放置した.
Quarto-introduction.qmd
はこの投稿を生成した原稿である. 一応 PDF 出力もできるように設定してある.
Knitr-Ja/
は最低限の日本語組版ができそうな PDF の設定例である. 一応 HTML 出力ともある程度互換性があるように設定している.
- 「最低限」なので文献リストは BibLaTeX を使用している. 日本語ユーザの多くは (u)pBibTeX に頼っているが, これは設定や使い方少し複雑なので, 別のファイル
Quarto-Ja-upbibtex.*
を用意している.
- (追記) upLaTeX でも動作させる例,
Knitr-ja-up-bx.*
を追加した. しかし現状は BXjscls の文書クラスにしか対応していない.
Jupyter-Py/
は Python カーネルを使用した Jupyter Notebook および, それを Quarto で HTML と PDF に変換したものである. Quarto の機能を見るためいろいろ変わった設定を試している.
Jupyter-R/*
は R カーネルを使用した Jupyter Notebook および, それを Quarto で HTML と PDF に変換したものである. (これが必要な状況があるのかはわからない)
Jupyter-Julia/
は Julia カーネルを使用した Jupyter Notebook および, それを Quarto で変換したものである. PDF は作っていないが, Gadfly.jl の保存形式の問題を回避できれば生成できると思われる.
Jupyter-slide/
は脚注で Jupyter や RISE の機能を批判しまくったので, 責任を取るべく Quarto ではスライド資料をより簡単に作れると実証したものである. カーネルは Python を使っている. PDF (beamer), PPTX, HTML (revealjs) の設定をしてあるが, 実際やってみたら HTML の出力はあまりよろしくなかった. pandas の出力はうまく表示できないが, Markdown の表はたぶん表示できると思う.
Knitr-slide/*
は .qmd
でスライドを作成する場合の例である. こちらは R を使っているので, 従来の R Markdown と比較してみてほしい.
公式ドキュメントでもいくつかの使用例が紹介されている.
rmdja では柔軟な設定ができるよう, pandoc テンプレートに大幅に手を加えたりフォーマット関数による動的な調整を行ったりしていたが, そういうのなしでエンドユーザ向けの設定だけでなるべく簡単に済ませようとした場合の設定を比較すると, 両者の設定はフィールド名以外同じになる.
R Markdown では YAML メタデータの記述はこうなる.
output:
bookdown::pdf_document2:
latex_engine: lualatex
documentclass: bxjsarticle
classoption:
- pandoc
- ja=standard
- jafont=haranoaji
Quarto で同等のことをやろうとすると, こうなる.
format:
pdf:
documentclass: bxjsarticle
classoption:
- pandoc
- ja=standard
- jafont=haranoaji
pdf-engine: lualatex
どちらもほぼ Pandoc の引数に対応させているだけなので, 結果として同じになる. また, 文書クラスに bxjsarticle
を使用することで, 日本語フォントの設定も簡単にしている. 上記では LuaLaTeX を使用しているが, XeLaTeX でも動作するはずである. これは bxjsarticle
が自動的にそれぞれのエンジンでの組版に必要なパッケージを読み込んでくれるためである. プリセットが気に入らず, メインフォント, サンセリフフォントなどを個別に設定したい, ウエイトを調整したいという場合は LaTeX コマンドで追加設定する必要がある. この設定は XeLaTeX か LuaLaTeX かで変わってくる. 前者は zxjatype を, 後者は luatex-ja のマニュアルを参考にしてほしい.
しかし, 現在は xelatex
よりも lualatex
の使用を推奨する. 理由は以下の2つ.
- zxjatype 作者が述懐するように, XeLaTeX を選択した場合に使われる
zxjatype
の組版はあまり厳格ではない
- LuaLaTeX は以前から (up-TeX や XeLaTeX と比べ) 処理が遅いと言われているが, TinyTeX を使用する環境では LuaLaTeX の遅さ以外にボトルネックがあるのであまり気にならない
ただし, beamer に関しては逆に禁則処理が厳格でなくても気になることがあまりなく, かつ人気のある metropolis テーマは XeLaTeX での動作を想定しているので XeLaTeX を使用したほうが良いだろう.
なお, ネット上では別のパターンの設定も存在するので, 蛇足気味だがそのあたりの違いについても書いておく.
例えば, 『TinyTeXのインストール & RmarkdownでPDF on Windows10』というページ. この設定例であればタイトルの Windows 10 に限らず比較的他のOSでも動作しやすい. ただし誤りでないがいくつか注意が必要である.
- TinyTeX を R パッケージを使わずにインストールしてしまっている. R も使うのなら tinytex パッケージ経由でインストールしたほうが管理が簡単である (ブログ筆者は Atom で編集する想定のためこうした?). 詳細は私の翻訳した公式ドキュメント参照.
- Noto フォントで揃える場合は
header-includes:
以下は不要で, 上記のように, classoption
内で jafont=noto
のようにプリセットを設定できる.
- 私の例では Noto ではなく TinyTeX からインストールできる原ノ味フォント (
haranoaji
) を使用している. 私が haranoaji
を指定しているのは, LuaLaTeX で Noto フォントを使う場合は noto-otc
とか noto-otf
とか名前が変わってややこしいため.
- あと IPA フォントをインストールするという指示があるが結局使ってない.
さらに, 例えば以下のようなページではまた別の設定例が紹介されている.
CJKmainfont
などを使う場合も確かに日本語フォントを指定し表示させられるが, 現在ではややバッドノウハウと思える. CJKfont は中国語の組版を想定したもの (xeCJK) であり, 日本語環境を想定した設定ではないため, 微妙に不自然になることがある (zxjatype も組版設定が甘いのでそこばかりしつこく突くのもフェアではないが). 現状一番簡単な設定の書き方として, これらの記事の下のほうでも少し紹介されている bxjscls シリーズの文書クラスを使うことをお薦めする. 現在は特にプリアンブルを書き換えたりしなくともエラーが発生しないようになっている (はず). このあたりの仕様が変わったのは比較的最近なので, 2-3年前の記事だとあまり反映されていないのだろう.
ただし, もしこのプリセットが納得行かず, 3種類のフォントでそれぞれ違う系統のものを使いたい場合はこの限りではない (しかしその場合も bxjscls でプリセットを指定した上で上書きしたほうが使いやすいはずである).
その他, 多くのブログ等で
header-includes:
- \usepackage{zxjatype}
- \usepackage[HOGEHOGE]{zxjafont}
のような zxjatype
や zxjafont
を手動で読み込む LaTeX コマンドを書く例を紹介している人がいるが, これらは XeLaTeX でのみ使用可能であり, また使用できるフォントはOSによって変わってくるため書き換えが面倒であり私はおすすめしない. これもやはり, bxjsarticle
であれば LuaLaTeX を使うか XeLaTeX を使うかによって必要なパッケージを自動で読み込んでくれる. ただし, beamer
の場合は日本語フォントを設定するオプションがないので自分で書く必要がある (詳しくは beamer のサンプルを参考に).
さらに日付の古いページだと,
output:
pdf_document:
...
documentclass: bxjsarticle
mainfont: ...
sansfont: ...
といった記述例を紹介するものが見られる. あるいは documentclass:
の設定が抜けているものも見られる. これらも一応動作するが, 欧文用の設定に日本語フォントを放り込んだだけなので, フォントスタイルの適用がおかしくなったり, 見出しの一部が英語になったりしてしまう. よって現在は積極的に使う必要はない.