[Stata]dyndocコマンドを使った出力をカスタマイズする

stata
Published

2020/07/09

dyndoc コマンドは,Stata 15 から実装されたコマンド。stataのコマンドと結果はもちろん,markdown形式で文章を書いた結果レポートみたいなものをhtmlファイルやdocxファイルに出力できます。

分析を変えてもその都度出力できるので,進捗報告のたびに結果の表をいちいちまとめたりしなくて良くなります。便利。

本文を書いてwordに出力すると,論文の結果パートをstataだけで作成できます。便利。

RでいうRmarkdownと似たような感じです。ただし,いろいろ超便利なRmarkdownと違って操作性が良くない。何もせずに使うと日本語は文字化けするし,数式も使えない。stataのサイトで配布されているheaderとcss使っても日本語文字化け問題は解決しないし,出力される表のデザインが気に入らない。いろいろな問題を解決するための方法をここにメモしておきます。

dyndocコマンドのマニュアルを一通り読んだ前提で書いています。
markdown,html,cssを使っていますが,この辺り全く知らなくてもとりあえずここに書いたことはできます(僕は dyndocの出力方法をいじる過程で初めてhtmlとcssを触った初心者ですので,よくわかってない部分があります)。


  1. 気に入らない点
  2. 問題の解決
    1. 日本語の文字化けを防ぐ
    2. 数式を入れる
  3. さらに使い勝手を良くするために
    1. ファイル形式は.doでもいい
    2. コード部分を折り畳む
    3. 目次をつける
    4. トップに戻るボタンをつける
    5. コマンドのハイライト
    6. デザインを抜本的に変える
  4. 色々組み込んだcssを作った

以下色々書きますが,結局のところこのコマンドをstataに読ませたいファイルの一番上に貼っておけば全部できるようになります。

<<dd_include: https://tomo-sakuma.github.io/stata_dyndoc_customize/stata_header.css>>

1. 気に入らない点

何も特別なことをしない状態のものを実行すると,日本語が文字化けします。数式は表示されないです(コードは載せないか載せるかの二択)。さらに,ブラウザの幅の広さに合わせて横幅いっぱいに文字が表示されます。

試しにsample.doというdoファイルに以下の内容が書かれているとして,

dyndoc sample.do,replace embedimage

を実行します

<<dd_version: 2>>
# Title
<<dd_display: "$S_DATE $S_TIME">>

This is an example

日本語は文字化けする

$$y=ax+b$$

~~~~
<<dd_do:>>
clear all

sysuse auto.dta

sum

eststo result1: /// 回帰分析
 reg price mpg

esttab result1 /// 結果の表示
 using test1.html ///
 ,replace ///
 star(* 0.1 ** 0.05 *** 0.01) ///
 b(3) se(3) brackets r2(3) ar2(3) aic(3) ///
 label varwidth(25)
<</dd_do>>
~~~~

何も工夫せずにやるとこうなる

2. 問題の解決

2.1 日本語の文字化けを防ぐ

一番単純な方法は,ファイルの最初(本文や内容の前)に以下のコードを貼り付けること。

<head>
  <meta http-equiv="content-type" charset="utf-8">
</head>

2.2 数式を入れる

そんな場合htmlで数式を表示するMathjaxを使う。上で使った<head></head> 内に以下のものを入れておくとtex形式の数式を出力できる。(なんか重複してる感じがするけど,一部抜いたらうまくいかなかったからこのままにしている)

$$ で囲むとディスプレイ形式, $ で囲むとインライン形式で数式を入れることができる。

<head>
  <script type="text/x-mathjax-config">
    MathJax.Hub.Config({
      tex2jax: {inlineMath: [['$','$'], ['\\(','\\)']]},
      displayAlign: "left",
      displayIndent: "2em"
    });
  </script>
  <script type="text/javascript" async
    src="https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS_CHTML">
  </script>
</head>

3. さらに使い勝手を良くするために

3.1 ファイル形式は.doでもいい

マニュアルでは.txt形式のファイルを読み込んでいる。

  1. do-fileで分析して
  2. .txtファイルに貼り付けて
  3. dyndocコマンドで.txtファイルを読み込んで出力

という感じ。面倒臭い。試してみると,.do形式のファイルを指定しても普通に動く。なので,

  1. .doファイルで分析しながら本文を書き
  2. dyndocコマンドで.doファイルを読み込んで出力

って感じで行ける(冒頭の例もそうやった)。なので,doファイルにコマンドも本文も書いておいて,そのファイルの冒頭にでも以下のようなdyndoc実行のためのコマンドを(html用の)コメントとしてつけておいたらいい。出力するときはこの部分だけ実行する。

<!-- dyndoc ファイル名.do,replace embedimage -->

3.2 コード部分を折り畳む

コードを表示して出力するか非表示にするかは,マニュアル通りにやれば指定できる。でもRmarkdownみたいに「コード部分を折りたたんでおいて,クリックしたら開くようにしたい。」という場合には工夫が必要(マニュアルには載っていない)。

dyndocコマンドを使うときにstataのコード囲む以下の書式

~~~~
<<dd_do>>
 /*ここにstataコードを書く*/
<</dd_do>>
~~~~

の前後に <details>をつければいい。

<details>
<summary> <b>Code</b> </summary>

~~~~
<<dd_do>>
 /*ここにstataコードを書く*/
<</dd_do>>
~~~~

</detail>

3.3 目次をつける

レポートが長くなったら目次をつけたい。そんな場合はmarkdownの目次が使える。本文の見出しがこんな感じだとすると

 ## 1項のタイトル

目次は

1. [1項のタイトル](#1項のタイトル)  
2. [2項のタイトル](#2項のタイトル)

という箇条書きを作り,本文のタイトルと同じもの(前に#をつける)を括弧で囲んでつける。()の中について,スペースは「-」でつなぐとか「.」は無視するとか例外もある。

3.4 トップに戻るボタンをつける

レポートが長くなったら目次に戻るボタンをつけたい。

<head><style>内に以下のように入れておく

<head>
  <style>
    .sticky {
      position: -webkit-sticky;
      position: sticky;
      bottom: 15px;
      float: right;
    }
 </style>
</head>

その上で,出力したいファイルの最初(タイトルの下とか)に

<a id=”top”></a>

ファイルの最後の行に

<div class=”sticky”>

[↑Top](#top)

</div>

を入れる。画面の右下にトップに戻るボタンが表示されるようになる。

3.5 コマンドのハイライト

Stataのsyntax highlightingをやってくれるStataxというのがある。 <head>内に以下のものを入れておくと使える。

<head>
  <script type="text/javascript" src='http://haghish.com/statax/Statax.js'></script>
</head>

各コマンドの入力部の前後に <pre class =”sh_stata”></pre>ををつける。コマンドの折り畳みも含めると,こんな感じ。入力辞書にでもショートカットとして入れておくといいかも(僕はsssって打つとこれが出るようにしてます)。

<details>
<summary> <b>Code</b> </summary>
<pre class="sh_stata">

~~~~
<<dd_do: noresults>>
/*ここstataコード*/
<</dd_do>>
~~~~

</pre></details>

3.6 デザインを抜本的に変える

フォントとか表示される横幅とかいろいろ変えたいって思ったら,cssファイルを作成しておき,doファイルの最初にcssを読み込むコマンドをつけておけば良い。(cssの内容をdoファイルにベタ打ちしても同じことはできるけど,ファイル長くなりすぎて肝心の分析の内容とかを確認しづらくなる。)

例えばhead.cssというファイルを作っておいて,doファイルの冒頭に

<<dd_include: /Users/(ファイルの場所)/head.css>>

をつけとくと,cssの内容を反映してくれる。


4. 色々組み込んだcssを作った

上に書いた日本語文字化け防止とか,トップに戻るボタンとか,数式の出力,コードのハイライトにとかができるようにしたcssをgithubに載せておきました。それを呼び出すのがこの記事の冒頭に書いたこれです。

<<dd_include: https://tomo-sakuma.github.io/stata_dyndoc_customize/stata_header.css>>

これをファイルの最初に書いておいて,上であげたdoファイル内の変更(コードの折りたたみなど)を加えると,こんな感じになります。さっきと同じように,sample2.doというdoファイルに以下の内容が書かれているとして,

dyndoc sample.do,replace embedimage

を実行します。

<<dd_include: https://tomo-sakuma.github.io/stata_dyndoc_customize/stata_header.css >>

<<dd_version: 2>>

# Title
<<dd_display: "$S_DATE $S_TIME">>

This is an example

日本語は文字化けする

$$y=ax+b$$

<details>
<summary> <b>Code</b> </summary>
<pre class="sh_stata">

~~~~
<<dd_do:>>
clear all

sysuse auto.dta

sum

eststo result1: /// 回帰分析
 reg price mpg

esttab result1 /// 結果の表示
 using test1.html ///
 ,replace ///
 star(* 0.1 ** 0.05 *** 0.01) ///
 b(3) se(3) brackets r2(3) ar2(3) aic(3) ///
 label varwidth(25)
<</dd_do>>
~~~~

</pre></details>

<<dd_include: test1.html>>

<div class="sticky">

[↑Top](#top)

</div>

Codeボタンを押したらこんな感じ。