【Rmarkdown】DiagrammeR::grVizがPDF出力されない時の対処方法

Rmarkdown

R Markdown でフローチャートやスキーム図を作る際、便利なのが DiagrammeR の grViz() です。

しかし、RStudio のアップデート後あたりから、PDF 出力時に突然エラーが発生し、図が表示されなくなってしまいました。

この記事では、

  • 発生したエラー内容
  • よく紹介されている対処法
  • 実際に解決できた方法

をまとめます。

対処に試行錯誤したので、同じ症状で困っている方の参考になれば幸いです。

発生したエラー

以下のようなコードを R Markdown(PDF 出力)で実行していました。

library(DiagrammeR)
library(webshot)
webshot::install_phantomjs()

DiagrammeR::grViz("digraph {
  graph [layout = dot, rankdir = TB]
  
  node [shape=rectangle]
  a [label='データ読込']
  b [label='前処理']
  c [label='可視化']
  d [label='解釈']
  
  # ノードIDでエッジを定義
  a -> b -> c -> d
  }")

すると knit 時に次のエラーが発生。

Error: Functions that produce HTML output found in document
targeting X output. Please change the output type of this
document to HTML. Alternatively, you can allow HTML output in
non-HTML formats by adding this option to the YAML front-matter
of your rmarkdown file:

  always_allow_html: yes

Note however that the HTML output will not be visible in
non-HTML formats.

結果として、PDF 内では図が空白になってしまいます。

原因は「HTML ウィジェット」

DiagrammeR::grViz() は内部的には HTML ウィジェットとして動作します。

そのため、HTML 出力では問題なく表示されても、PDF 出力ではそのまま埋め込めずエラーになります。

以前は webshot + phantomjs を使った方法で回避できていましたが、環境更新後はうまく動作しなくなりました。

インターネット上の試した解決方法

R Markdown Cookbook の方法

まず試したのが、R Markdown Cookbook に掲載されている方法です。

9.2 HTML ウィジェットを表示する | R Markdown クックブック
本書は, 各種ツールを最大限活用するために役立つよう, あまり知られていない小ワザや簡潔で実践的な裏ワザの例を紹介します. 本書を読んだ後には, R Markdown 文書が, プレーンテキストから変換され, 処理の各ステップステップのほぼ...

キャッシュ削除やパッケージ再読み込みも試しましたが、改善しませんでした。

Stack Overflow の方法

次に、かなり症状が近い Stack Overflow の投稿を参考にしました。

rmarkdown diagrammeR blank output to PDF
I would like to include a diagram from diagrammeR in R markdown and render it to PDF.I installed webshot and phantomJS a...

しかし、こちらも改善せず。

原因を調べると、webshot2 系は Chrome / Chromium ベースで動いているようで、Safari をメイン利用している自分の環境ではうまく連携できていなかったようです。

最終的に解決した方法

結論から言うと、

SVG に変換 → PDF に変換 → include_graphics()で読み込む

という方法で解決しました。

使用するパッケージ

今回使ったのは以下の 2 つです。

最初に試したコード

library(DiagrammeR)
library(DiagrammeRsvg)
library(rsvg)

DiagrammeR::grViz("digraph {
  graph [layout = dot, rankdir = TB]

  node [shape=rectangle]
  a [label='データ読込']
  b [label='前処理']
  c [label='可視化']
  d [label='解釈']

  a -> b -> c -> d
}") |>
  export_svg() |>
  rsvg_pdf(tmp <- tempfile(fileext = ".pdf"))

knitr::include_graphics(tmp)

しかし、次のエラーが発生。

Error in read_data(svg) :
  Argument 'svg' or 'css' must be a file path, url, or raw vector.

解決ポイント:charToRaw() を挟む

原因は、rsvg_pdf() がファイルパスまたは raw vector を要求していたことでした。

そこで charToRaw() を追加。

library(DiagrammeR)
library(DiagrammeRsvg)
library(rsvg)

DiagrammeR::grViz("digraph {
  graph [layout = dot, rankdir = TB]

  node [shape=rectangle]
  a [label='データ読込']
  b [label='前処理']
  c [label='可視化']
  d [label='解釈']

  a -> b -> c -> d
}") |>
  export_svg() |>
  charToRaw() |>
  rsvg_pdf(tmp <- tempfile(fileext = ".pdf"))

knitr::include_graphics(tmp)

これで無事に PDF に図が表示されました。

まとめ

R Markdown の PDF 出力で DiagrammeR::grViz() が表示されなくなった場合は、

export_svg() |> charToRaw() |> rsvg_pdf()

を使った SVG → PDF 変換が有効でした。

同じ問題で困っている方の参考になれば嬉しいです。

広告

Amazonアフィリエイトでブログ運営しています。
応援いただけると嬉しいです。


ネスカフェ 香味焙煎 ひとときの贅沢 スティック ブラック 20P,箱,レギュラー ソリュブル コーヒー,個包装


AHMAD TEA(アーマッドティー) クラシックセレクション ティーバッグ 20袋

タイトルとURLをコピーしました