ユーザ用ツール

サイト用ツール


メモ:rmarkdown

差分

このページの2つのバージョン間の差分を表示します。

この比較画面へのリンク

両方とも前のリビジョン前のリビジョン
次のリビジョン
前のリビジョン
メモ:rmarkdown [2021/03/06 21:36] – [数字の桁そろえ] Wiki Editorメモ:rmarkdown [2023/06/22 11:00] (現在) – [RStudio ServerでRMarkdownのチャンク出力のフォント設定] Wiki Editor
行 141: 行 141:
      
   ```   ```
- +===== YAMLヘッダの注意点 ===== 
 +YAMLヘッダからLatexのプリアンブルにコマンドを渡すとき、「#」を含めたい時がある。そのまま記述すると、YAMLのコメントアウトになってしまい、エラーになってしまう。その場合は、行をクォートすればよい。 
 + 
 +   
 +  - \foobar{#1} 
 +   
 + 
 +上記ではエラーとなるため 
 + 
 +   
 +  - '\foobar{#1}' 
 +   
 + 
 +のように、シングルクォートでくくるとよい。 
 + 
 + 
 +===== RmarkdownにLatexコマンドを直接埋め込む ===== 
 +Rmarkdown内に「\」で始まるコマンドを直接書けば、単純なコマンドならばpandocが自動的にLatexコマンドと判断してそのまま利用できる。しかし、複雑なコマンドは文字列として解釈されてしまい、Latexソースに変換する段階でエスケープされてしまう。それを回避するためには、Latexチャンクで直接Latexコマンドを記載するとよい。 
 + 
 +  ```{=latex} 
 +  Latexコマンド... 
 +   
 +  ``` 
 + 
 +チャンクに「=latex」と指定すれば、チャンク内はすべてLatexにそのまま渡される。
  
 ===== パラグラフ間の余白(パラグラフ送り) ===== ===== パラグラフ間の余白(パラグラフ送り) =====
行 399: 行 423:
  
  
 +===== 丸囲み数字等のフォント =====
 +Rmarkdownからxelatexを経由してPDFを作成する際に、丸囲み数字など(①)がフォント抜けで豆腐になっていたのを解決。問題は単純なフォント設定だったが、フォント設定は基本的に変えたくなかったので、いろいろ調査してわかったこと。
 +
 +xelatexはTTFフォントを直接指定することができる便利なtexなので、Rmarkdownからの出力はこれを利用している。この時、日本語を利用するために以下の設定をしている。ドキュメントクラスの読み込みでfontspecやzxjatypeはusepackageをしなくてもよいかもしれない。
 +
 +RmakdownのYAMLヘッダ(該当箇所のみ)
 +  documentclass: bxjsarticle
 +  classoption: xelatex,ja=standard,base=10.5pt,jbase=10.5pt,a4paper
 +  header-includes:
 +    # 欧文フォントの指定
 +    - \usepackage{fontspec}
 +    - \setmainfont{Times New Roman}
 +    - \setsansfont{Times New Roman}
 +    # 和文フォントの指定
 +    - \usepackage{zxjatype}
 +    - \setCJKmainfont[BoldFont=IPAexGothic]{IPAexMincho}
 +    - \setCJKsansfont{IPAexGothic}
 +
 +
 +Texソースでは以下のように展開される。
 +  \documentclass[xelatex,ja=standard,base=10.5pt,jbase=10.5pt,a4paper]{bxjsarticle}
 +  \setmainfont{Century}
 +  \setsansfont{Century}
 +  \setCJKmainfont[BoldFont=IPAexGothic]{IPAexMincho}
 +  \setCJKsansfont{IPAexMincho}
 +
 +使っているフォントはともかくとして、以上の設定でだいたいスムーズにタイプセットしてPDFがうまく生成されていたのだが、丸囲み数字などがフォント抜けしてしまい、その都度丸囲み数字を生成するコードを挿入していた。文章を書いている場合には、自分で丸囲み数字を使う箇所を認識しているので問題はないが、アンケートの自由記述欄などテキストデータを読み込んで、一括して整形・出力するようなコードを書くと、どうしても入力された文字に混ざってしまう。逐一見つけて置換などをしても、気づかないフォント抜けなどが発生してしまうことがあり、いままで気づいた文字を置換リストに貯めていたが、非効率だしユニコードの世界では解決できるはずだと思い調査。
 +
 +原因は非常に単純な点にあった。問題は、丸囲み数字の箇所が「欧文」として扱われており、Times New Romanにコードポイントに対応するフォントが用意されておらず、フォントが抜けてしまう様だった。試しに欧文フォントをIPAフォントに変えてみると、ごく普通に丸囲み数字もPDFで表示できる。丸囲み数字を入力するのが日本語IMEで変換するため、てっきり日本語の全角文字扱いだと思っていたが、かつてと異なりユニコードでは①はU+2460というコードポイントが割り当てられており、このコードが入力されている。そして、このコードがある範囲がxelatexでは欧文として扱われるため、欧文フォントの設定が適用されていたためにフォント抜けが発生していた。
 +
 +単純な解決策は、欧文もすべて日本語フォントにすること。IPAex明朝などは、半角文字もきれいに出力できるので、これはこれでよい。しかし、どうしてお欧文には別フォントを利用したい場合、丸囲み数字の箇所だけフォント指定するとか、段落単位で逐一フォント指定するとか個別対応が必要となる。これでは、個別に置換するのと手間はあまり変わらない。そこで以下を参考に設定を追加。
 +
 +
 +  * [[http://zrbabbler.sp.land.to/zxjatype.html]]
 +  * [[https://texwiki.texjp.org/?xeCJK]]
 +  * [[https://ftp.kddilabs.jp/CTAN/macros/xetex/latex/xecjk/xeCJK.pdf]]
 +  * [[https://suzusime-log.hatenablog.jp/entry/2017/04/15/210327]]
 +
 +  \xeCJKDeclareSubCJKBlock{kigou}{"20A0 -> "2BFF}
 +
 +上記のように、xeCJKパッケージの\xeCJKDeclareSubCJKBlockで、和文として扱うコードの範囲を指定してやる。単純に和文として扱うだけなら、上記のように必要な個所のコードを指定すれば、全体で設定している和文フォントが利用される。「kana」は識別名なので何でもよい。範囲の指定は、コードポイントでも、コードポイントに対応する文字でも指定できるようだ。また、必要に応じてここで指定したブロックだけ別フォントを割り当てることも可能。<del>ここでは横着して、とりあえずASCII文字+α以上のコードポイントはすべて和文と指定して丸囲み数字等をすべて日本語フォントにしてしまうが、もう少し丁寧に設定する方が望ましいだろう。</del>範囲指定の際は、Unicodeのブロック表などを参照するとよい。
 +
 +\xeCJKDeclareSubCJKBlockでASCII以外のほぼすべてのコードポイントを指定していたが、やはり横着したのはよくなかった。詳細は調べていないが、ここで指定されたブロックは、文字送りや禁則処理のルールが別扱いになるようで、「。」が行頭に出てしまったりと、美しい組版にあらない。ということで、記号が入っているブロックに絞って指定する。とりあえず「"20A0 -> "2BFF」の範囲としたが、様子を見て微調整する。とりあえず丸囲み数字の範囲は抑えているので、当面は問題ないはず。
 +
 +  * [[https://ja.wikipedia.org/wiki/Unicode#%E3%83%96%E3%83%AD%E3%83%83%E3%82%AF%E3%81%AE%E4%B8%80%E8%A6%A7]]
 +
 +
 +
 +
 +
 +
 +===== kableから出力されるLatexコードを加工する =====
 +
 +kableExtraのcollapse_rowsを使って繰り返しのあるセルをまとめてBooktabs形式の罫線を引くと、まとめたセルの縦方向の位置がおかしくなる。
 +
 +  collapse_rows(1:2, valign="top", latex_hline="full")
 +  
 +この場合、縦に結合したセル内の文字が、結合していない行の一番上の行と同じところに来てほしいが、自動的にはそろわない。kableExtraの作者によると、Latexのmultirowの長さ計算の問題らしい。latex_hline="major"などで、罫線を引かないようにすれば計算が合うので問題ないが、罫線を入れたいときは出力されるLatex側のコードを無理やり書き換えて対応する。
 +
 +  collapse_rows(1:2, valign="top", latex_hline="full") %>
 +    gsub("\\\\multirow\\[t\\]\\{-3\\}\\{\\*\\}","\\\\multirow[t]{-3}{*}[3.5mm]", .)
 +
 +このように、\multirowのコマンドの部分の<vmove>オプションを入れるように書き換える。今のところ、出てきたコードに場当たり的に修正を加えるしか思いつかない。\multirowの開発者の人に頑張ってもらいたい。。
 +
 +===== kableで出力するテーブル内の文字の回転 =====
 +ラベルに長い文字列を使うようなとき、表頭の文字列を90度回転して縦方向にしたい時がある。その場合は、kableExtraのrow_specを使えばよい。
 +
 +  kable() %>
 +  .... %>%
 +  .... %>%
 +  row_spec(0, angle = -90)
 +
 +これで0行目=ヘッダの文字列を90度回転できる。この他にも、セルごとに個別に設定するには、cell_specも使える。
 +
 +  DATA[1, 5] <- cell_spec(DATA[1, 5], "latex", angle = 90)
 +
 +cell_specはセル内にLatexなりHTMLのコードを直接埋め込む。したがって、個々のセルに対して処理を行っておく必要がある。テーブルのヘッダの場合は、cell_specを利用して必要なコードを埋め込んだヘッダのベクトルを生成し、kableのcol.namesに渡すという手間がかかる。なおcell_specはLatexのコードをデータに直接埋め込むので、kabelのオプションで「escape=FALSE」を指定しておかないと、コードがそのまま文字として出力されてしまう。
 +
 +上記は両方指定しても効果を発揮する。そのため、行全体を90度回転させ、特定のセルだけ-90度回転するように指定すれば、そのセルだけ回転させないということができる。
 +
 +文字列を回転する際に、回転の中心点を決めることができる。angleを指定すると、Latex側では\rotateboxで文字列が回転される。この時、標準では文字列の左端を中心に回転が行われる。「angle=90」ならば、文字列の先頭を中心に反時計回りに回転するので、行内の全てのセルにangle=90が設定されている場合、文字列の先頭が下にきて先頭がセルの下で揃うことになる。逆に「angle=-90」とすると、文字列の先頭を中心に時計回りに回転するため、文字列の先頭が上にきてセルの上で先頭が揃う。
 +
 +この時、angle=-90で時計回りに回転しつつ、文字列をセルの下で揃えたい場合には、回転の中心を文字列の末尾=右端にする必要がある。右端を中心に時計回りすると、行頭が持ち上がる形で回転し、文字列はセルの下側で揃うことになる。しかしkableExtra側ではオプションがないので、Latexのコマンドで調整する。angleを設定した際に利用される\rotateboxのオプションは以下の通り。
 +
 +  \rotatebox[回転の中心など]{角度}{対象の文字列}
 +
 +kableExtraでは\rotateboxの回転の中心は指定されずデフォルトでハードコーディングされているため、このページに記載したようにLatexのコードを文字列として変数に入れ無理やり正規表現で書き換えるか、一時的に\rotateboxコマンドの定義を書き換える。後者の場合は、以下のようにする。
 +
 +  \let\orgrotatebox\rotatebox%
 +  \renewcommand{\rotatebox}[2]{\orgrotatebox[origin=r]{#1}{#2}}%
 +
 +基本的には、renewcommandで\rotateboxの定義をオプションを指定した状態に書き換えることで、kableから呼ばれたときに、改変された\rotateboxが用いられるため、文字列の右端を中心に回転され目的の挙動となる。ここで注意が必要なのは、\rotateboxの再定義に\rotateboxコマンドを直接使うと、再帰的に展開されてリソースを食い尽くしてエラーとなる(ハマった)。そこで、いったん\letコマンドを使って一旦「\rotatebox」を「\orgrotatebox」にコピーしておき、コピーしたコマンドを使って\rotateboxの定義を再定義する。コピーしておいたコマンドは、ここでの変更を元に戻す際にも使う。なお、行末の「%」はコマンドは、Latexで単一改行が空白として扱われてコマンドが連続したように解釈され、不用意なエラーを生じることを回避するもので、ここでは必要ないかもしれない。
 +
 +\renewcommandの使い方は
 +
 +  \renewcommand{対象のコマンド}[引数の数]{再定義したコマンドの内容}
 +
 +なので、ここでは\orgrotateboxにコピーしたオリジナルの\rotateboxを使って、オプションの回転中心点を決める[origin=r]を指定した状態の\rotateboxコマンドを再定義している。origin=rで文字列の右端を回転軸にする。他にもx,yで細かく指定することも可能。
 +
 +
 +===== RStudio ServerでRMarkdownのチャンク出力のフォント設定 =====
 +
 +RStudioでRMarkdownファイルを作成すると、チャンクの出力をインラインで確認できる。この時、ggplot等でグラフを出力する場合のグラフィックデバイスはTools > Global Options > General > Graphics > Graphics Device > Backendで指定できる。ここでCairoやAGGを選択すれば日本語も出力できるが、デフォルトのフォントの指定ができない。
 +
 +ggplot等でフォントの指定をしなければ、標準のfallbackフォントが使われる。RStudio ServerをLinuxで動かしていると、Linux側の設定に従う。そのままでも日本語は表示されるといえばされるが、字形がどうも中国語っぽいものが使われるので、任意のものにしたい。
 +
 +そこで、Linuxの標準のフォント設定を変更する。RStudio以外にも影響するが、他も変更したいので問題なし。これでRStudioのセッションを再起動すれば、フォールバックフォントが変更されているのでチャンクのインラインプレビューの描画にも反映される。本来は上記のグラフィックデバイスの設定に追加オプションでフォント等の指定もできるとよいのだが。。
 +
 +  * /etc/fonts/local.confを以下のように作成する
  
 +  <?xml version="1.0"?>
 +  <!DOCTYPE fontconfig SYSTEM "fonts.dtd">
 +  <fontconfig>
 +          <match target="pattern">
 +                  <test qual="any" name="family">
 +                          <string>mono</string>
 +                  </test>
 +                  <edit name="family" mode="assign" binding="same">
 +                          <string>Noto Sans Mono CJK JP</string>
 +                  </edit>
 +          </match>
 +          <match target="pattern">
 +                  <test qual="any" name="family">
 +                          <string>sans serif</string>
 +                  </test>
 +                  <edit name="family" mode="assign" binding="same">
 +                          <string>Noto Sans CJK JP</string>
 +                  </edit>
 +          </match>
 +          <match target="pattern">
 +                  <test qual="any" name="family">
 +                          <string>sans-serif</string>
 +                  </test>
 +                  <edit name="family" mode="assign" binding="same">
 +                          <string>Noto Sans CJK JP</string>
 +                  </edit>
 +          </match>
 +          <match target="pattern">
 +                  <test qual="any" name="family">
 +                          <string>serif</string>
 +                  </test>
 +                  <edit name="family" mode="assign" binding="same">
 +                          <string>Noto Serif CJK JP</string>
 +                  </edit>
 +          </match>
 +          <match target="pattern">
 +                  <test qual="any" name="family">
 +                          <string>sans</string>
 +                  </test>
 +                  <edit name="family" mode="assign" binding="same">
 +                          <string>Noto Sans CJK JP</string>
 +                  </edit>
 +          </match>
 +  </fontconfig>
  
メモ/rmarkdown.1615034206.txt.bz2 · 最終更新: 2021/03/06 21:36 by Wiki Editor

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki