0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

TypstとRの連携

Posted at

Typstとは

TypstはポストLaTeXと目される高度な組版言語で、LaTeXに比べて構造を直感的に表現できる文法や、スタイルの再利用性の高さ、処理速度の速さなどが魅力です。Rとの連携については現在のところ、TypstではknitrやRMarkdownのように文書内に直接Rのコードを組み込むことはできませんが、Typstの外部データ読み込み機能とリアルタイムプレビューを活用すれば、RMarkdownよりも連携しやすいかもしれません。

Rとの連携

Rの分析結果をTypst内で用いるには、Rオブジェクトをjsonyamlなどの形で外部ファイルとして保存しておく必要があります。ここでは、json形式で保存し、それをTypstで利用する場合について説明します。

まず、Rでjson形式のファイルを操作するためには、jsonliteなどのパッケージが必要です。

library(jsonlite) ## jsonファイルの読み書き用

そして、Rの分析結果やデータで、Typstで利用したい部分をjson形式で保存するようにします。分析ごとにjsonファイルにしてもいいですが、1つのリストにまとめておいた方が扱いやすいと思います。なお、lmオブジェクトなど複雑な構造を持つオブジェクトの場合は、必要な要素を抜き出してjsonファイルに変換する必要があります。次の例では、lavaanによる分析結果のうち、パラメータ推定値と適合度指標を取り出してリストにまとめ、それを要約統計量(summary)と合わせてjsonファイルに保存しています。

# モデルの推定
fit <- sem(model, data = data, std.lv = TRUE)

# 結果の表示
summary(fit, standardized = TRUE, fit.measures = TRUE)

# パラメータ推定値
params <- parameterEstimates(fit, standardized = TRUE)

# 適合度指標
fitmeasures <- fitMeasures(fit)

# 結果をリストにまとめる
result_list <- list(
  summary = summary_table,
  parameterEstimates = params,
  fitMeasures = as.list(fitmeasures)
)

必要な変数あるいはオブジェクトのjsonファイルへの書き出し処理は、分析スクリプトの最後に書いておくなどして、スクリプトを修正した場合にそれがjsonファイルに反映されるようにしておくのがよいでしょう

作成したjsonファイルは、Typstの文書内で#let 変数名 = json("ファイルパス")とすることで読み込めます。ここでは、次のようにしてrjsonという名前でjsonファイルを読み込みました。

#let rjson = json("../data/sem_result.json")

このようにして読み込むと、本文中で#rjson.fitMeasures.at(0)のようにしてその内容を参照できるようになります。データが名前付きリストで保存されている場合、「.fitMeasures」のように名前でアクセスできますし、そうでないリストでは「.at(0)」のように位置でアクセス可能です。このとき、リストの開始位置は1ではなく0である点には注意が必要です。

なお、VS CodeのTinymist Typst機能拡張を使っている場合、#rjson.まで入力すると補完候補として要素名が上がってきますし、その時点で#rjsonの中身が即時プレビューで文書中に表示されるので、元のjsonファイルを開いて確認する必要もありません。

Rデータからの表の作成

Rとの連携の例として、Rで出力した要約統計量を表にしてみます。ここでは、booktabszeroパッケージを使って、心理学系論文スタイルの表にしてみます。

#figure(
  caption: [自己効力感、ストレス、課題成績の平均値および標準偏差],
  {
    set text(size: 9pt)
    show: format-table(str, (digits: 2), (digits: 2))
    table(
      stroke: none,
      columns: 3,
      align: (left, center, center),
      toprule(),
      table.header([変数],[平均値],[標準偏差]),
      midrule(),
      [自己効力感],[#rjson.summary.at(0).Mean],[#rjson.summary.at(0).SD],
      [ストレス],[#rjson.summary.at(1).Mean],[#rjson.summary.at(1).SD],
      [課題成績],[#rjson.summary.at(2).Mean],[#rjson.summary.at(2).SD],
      bottomrule()
    )
  }
)

table.png

今回はシンプルは表1つだけなので、表の要素には#rjsonの値を1つ1つ指定していますが、表の行や列が多い場合は、for文などを使って効率化するとよいでしょう。

Rで作成した図の利用

表ではなく図を用いたい場合は、ggplot2で作図したものをSVG形式で保存してTypstに取り込むのがいいと思います。少なくとも私の環境(Mac)では、図に日本語が含まれていても問題なく表示できます。なお、Typstは、標準ではPDFを読み込めませんので注意してください。ggplot2で作成した図をSVGファイルに保存するには、svgliteというRパッケージを使用します。

Rのコード
# 散布図+回帰直線
p <- ggplot(data, aes(x = SelfEfficacy, y = Performance)) +
  geom_point(alpha = 0.6, color = "#0072B2") +
  geom_smooth(method = "lm", se = TRUE, color = "#D55E00") +
  labs(
    x = "自己効力感",
    y = "課題成績"
  ) +
  theme_minimal(base_size = 10)

# SVGファイルに保存
ggsave("../figs/selfefficacy_performance.svg",
       plot = p, width = 8, height = 6, units = "cm")
Typstのコード
  #figure(
    image("../figs/selfefficacy_performance.svg"),
    caption: [
      自己効力感と課題成績の散布図および回帰直線
    ],
  )

figure1.png

Rデータを利用した作図

パス図などを作成したい場合、Rでの作図は思い通りにならず大変なので、LaTeXの場合にはTikZという描画ライブラリを用いてLaTeX内で作成していました。じつをいうとggplot2の図は個人的にあまり好きではないので、LaTeXで文書を作成する際は、折れ線グラフなどもデータだけ書き出して、PGFPlotsでLaTeX内で作成することも多くありました。そちらの方が細かい調整がきくし、仕上がりも(少なくとも自分にとっては)綺麗だったからです。

Typstには、なんとこのTikZやPGFPlotsに相当するパッケージも用意されています。ここでは、試しにcetzfletcherというパッケージで簡単なパス図を描いてみることにします。

// スクリプトを見やすくするために、前もって係数を変数に代入
#let b_se_st = rjson.parameterEstimates.at(0).est
#let b_st_pf = rjson.parameterEstimates.at(1).est
#let b_se_pf = rjson.parameterEstimates.at(2).est

#figure(
  caption: [`cetz`と`fletcher`を用いて作成したパス図],
  block[
    // 図の中のフォントの設定
    #set text(size: 9pt, font: "Source Han Sans JP", weight: 400);
    #diagram(
      node((0, 0), [自己効力感], stroke: .5pt),
      edge(num(digits:2)[#b_se_st], "-|>"),
      node((2, -1), [ストレス], stroke: .5pt),
      edge(num(digits:2)[#b_st_pf],"-|>"),
      node((4, 0), [課題成績], stroke: .5pt),
      edge((0,0),(4,0),num(digits:2)[#b_se_pf], "-|>")
      )
  ]
)

figure2.png

この例では、図中のパスに示した係数は、すべてrjsonから値を持ってきています。そのため、後で計算のやり直しが発生したとしても、その際にjsonファイルがちゃんと更新されるようになっていれば、(モデルが変わらない限り)図を書き直す必要は一切ありません。

ところで、knitrやRMarkdownの場合、文章に修正を加えただけでもRのスクリプトを含めて文書全体をコンパイルしなくてはなりません。Rのコードブロックについてはある程度キャッシュが効くものの、MarkdownやLaTeXは本文のコンパイルにもそれなりの時間がかかるので、それらが積み上がると結構な時間のロスになります。

しかし、このようにjson(またはyaml)を介してRとやり取りすると、文章に修正が必要な場合はTypstのファイルを編集すればいいだけで、Rスクリプトの再実行は一切必要ありません。なので、一瞬で修正が終わります。Rスクリプトに修正を加える場合も、Rスクリプトを修正して実行しなおせば、Typst上の表示はリアルタイムで最新のものに更新されていきます。その点もすごく嬉しいところです。

おわりに

今回の説明用に作成したファイル一式は下記のリンク先に置いてあります。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?