試験的にMarkdownで文章を書いてみた
はじめに
R StudioでMarkdown方式で文章を書いてみた。とりあえず、論文やレポート執筆のための最低限の機能を網羅した感じかな。これ以上の機能については、実際に使用しながらこれから試していく。以下、完全に自分用のメモ。
コード
この記事もMarkdown方式で書いており、以下のコードもMarkdown方式で書いているので、コード内容が本ブログの編集にも反応してしまう。よって、簡単に埋め込む。
---
title: "テスト論文"
author: "伊達のメモ"
date: "2019年5月2日"
output:
pdf_document:
latex_engine: lualatex
number_sections: TRUE #見出しの番号true
toc: TRUE #目次の作成の有無
toc_depth: 3 #目次の深さ
documentclass: ltjsarticle
bibliography: ref.bib
---
library(tidyverse)
library(knitr)
#チャンクの一括設定 特に、図の算出方法をここで示す。
opts_chunk$set(fig.keep = "high", #チャンク内の図のどれを表示するか
fig.show = "asis", #文章全体のどこに図を配置するか
dev = "png", #図の出力の形式
dpi = 150, #図の解像度
# fig.width = 5, #図の出力幅
# fig.height = 4, #図の出力高さ
fig.pos = "t", #図をどこに出すか
fig.keep = "high" #チャンク内のプロットのどれを表示するか
)
# 問題の所在
今日では(私の中で)R Studio内でMarkdown方式で文章を記述する方法に着目が集まっている。そこで以下のように乱数を発生させて、試験的に文章を書いてみた。なお、ところどころ論文執筆のために必要なちょっとしたテクニック[^1]を入れる。
[^1]:例えばこのような注釈のように。
z1 <- rnorm(n = 1000, mean = 50, sd = 10)
z2 <- rnorm(n = 1000, mean = 50, sd = 10)
r <- 0.6 #相関係数
y <- rnorm(n = 1000, mean = 50, sd = 10)
x1 <- r*y + sqrt(1 - r^2)*z1
x2 <- r*y + sqrt(1 - r^2)*z2
data <- as.tibble(cbind(y, x1, x2))
# 分析
## 記述統計
次に、上記で発生させた乱数の記述統計量を確認する。
最小値 <- data %>% apply(2, min) %>% round(2)
平均値 <- data %>% apply(2, mean) %>% round(2)
最大値 <- data %>% apply(2, max) %>% round(2)
標準偏差 <- data %>% apply(2, sd) %>% round(2)
cbind(最小値, 平均値, 最大値, 標準偏差)
このように、結果を簡単に出力することができる。ただし、これだとpublish-readyではない。でも問題ない。Markdownなら表も綺麗に書けちゃう。しかも、その表の中にRのコードを埋め込むこともできるため、いちいち分析をし直すたびに数を書き直す必要はない。例えば、このような図ができる。
|変数|最小値|平均値|最大値|標準偏差|
|:---|:----:|:----:|:----:|:------:|
|y |`r min(y) %>% round(2)` |`r mean(y) %>% round(2)` |`r max(y) %>% round(2)` |`r sd(y) %>% round(2)` |
|x1|`r min(x1) %>% round(2)`|`r mean(x1) %>% round(2)`|`r max(x1) %>% round(2)`|`r sd(x1) %>% round(2)`|
|x2|`r min(x2) %>% round(2)`|`r mean(x2) %>% round(2)`|`r max(x2) %>% round(2)`|`r sd(x2) %>% round(2)`|
Table: 記述統計量 \label{smry_table0}
さらに良いことに、labelを`\label{smry_table0}`としてあげれば、この表について言及するときに`\ref{smry_table0}`と打てば番号を呼び出すことができる。表\ref{smry_table0}のように。
また、以下のように`kable`を利用することでも書ける。
min <- data %>% apply(2, min) %>% round(2)
mean <- data %>% apply(2, mean) %>% round(2)
max <- data %>% apply(2, max) %>% round(2)
sd <- data %>% apply(2, sd) %>% round(2)
smry_table <- cbind(min, mean, max, sd)
kable(smry_table,
col.names = c("最小値", "平均値", "最大値", "標準偏差"),
caption = "記述統計量 \\label{smry_table1}")
問題点があるとすれば、表の挿入位置は自動でできないこと。コードを書くとこをずらすしか方法はないっぽい。何か良い方法があれば良いのだが。ただし、後述するようにlatex形式で書いちゃえば問題ない。
次に図の挿入についてもやってみる。作成した変数間のplot図を作成する。これは、チャンクの最初のところで`{r, fig.cap="散布図 \\label{fig01}"}`と打ってあげれば良い。こうすると、`\ref{fig1}`で図番号を呼び出せる。例えば、図\ref{fig1}のように。
data %>%
ggplot(mapping = aes(x = x1, y = y)) +
geom_point(alpha = 0.6, size = 0.5) +
xlab("x1 日本語もいける") + ylab("y") + theme_gray (base_family = "HiraKakuPro-W3")
表については、その位置を指定できる。
## 数式と回帰分析
それでは次に、数式も綺麗に書けるので、それを試す。
例えば、このような数式をtex形式で簡単に書ける。しかも、R studio内でその場で式を変換してくれるので、助かる。
$$y_i = \alpha + \beta x_{1i} + \beta x_{2i} + e_i \tag{1} $$
$$\hat{y} = \alpha + \beta x_{1i} + \beta x_{2i} \tag{2}$$
$$argmin \sum_i ^N e_i ^2 = argmin \sum_i ^N (y_i - \hat{y})^2 \tag{3}$$
&emso;では次に、回帰分析を行なってみる。コードは以下の通り。
summary(lm(y ~ x1 + x2))
もちろん、これだとpublication-readyな表ではない。そこで、まず以下のようにコードを書いて、必要な統計量を得る。
p_judge <- function(p){
if(0.05 <= p & p < 0.1){rec <- "†"}
if(0.01 <= p & p <0.05){rec <- "*"}
if(0.001 <=p & p <0.01){rec <- "**"}
if(p < 0.001){rec <- "***"}
if(0.1 <= p){rec <- "n.s."}
print(rec)
} #有意水準を判断する関数
rec <- summary(lm(y ~ x1 + x2)) #分析結果収納
beta <- round(rec$coefficients[,1], 3) #係数取り出し
sd.error <- round(rec$coefficients[,2] , 3) #標準誤差取り出し
p.value <- rec$coefficients[,4] #係数のp値取り出し
coef.sig <- numeric(length(p.value)) #以下の有意水準測定結果の入れ物
for(i in 1:length(p.value)){
coef.sig[i] <- p_judge(p.value[i])
} #係数の有意水準測定
adj.r.squared <- round(rec$adj.r.squared, 3) #自由度調整済みr2
f.test <- df(x = rec$fstatistic[1],
df1 = rec$fstatistic[2], df2 = rec$fstatistic[3]) #f検定のp値
f.test.sig <- p_judge(f.test) #f検定の有意水準
ここで、回帰表のような複雑な表はMarkdownではなかなかできないっぽい。いや、できるのだが細かい指定ができないので不便。そこで、latex方式で書く[^2]。
\begin{table}
\caption{回帰分析の結果}
\begin{center}
\begin{tabular}{l r l c}
\hline
変数 & 係数 & & 標準誤差\\
\hline
切片 & `r beta[1]` & `r coef.sig[1]` & `r sd.error[1]`\\
x1 & `r beta[2]` & `r coef.sig[2]` & `r sd.error[2]`\\
x2 & `r beta[3]` & `r coef.sig[3]` & `r sd.error[3]`\\
\hline
調整済みR$^2$ & \multicolumn{3}{c}{`r adj.r.squared`}\\
F値 & \multicolumn{3}{c}{`r round(rec$fstatistic[1], 3)``r f.test.sig`}\\
\hline
\multicolumn{4}{l}{$^{***}p<0.001$, $^{**}p<0.01$, $^*p<0.05$}\\
\end{tabular}
\end{center}
\end{table}
そうすると表3のように出力される。しかも、ページの上に表示してくれる。また、文章中にRコードを入れることもできる。例えば、「x1の係数は`r beta[2]`であった」という文章が作成できる。
参考文献はbibtexでもいけるが、よくわからんかったのと、bibtexは文章作成の邪魔になることもあったので、手動で。
\begin{table}
\caption{回帰分析の結果}
\begin{center}
\begin{tabular}{l r l c}
\hline
変数 & 係数 & & 標準誤差\\
\hline
切片 & `r beta[1]` & `r coef.sig[1]` & `r sd.error[1]`\\
x1 & `r beta[2]` & `r coef.sig[2]` & `r sd.error[2]`\\
x2 & `r beta[3]` & `r coef.sig[3]` & `r sd.error[3]`\\
\hline
調整済みR$^2$ & \multicolumn{3}{c}{`r adj.r.squared`}\\
F値 & \multicolumn{3}{c}{`r round(rec$fstatistic[1], 3)``r f.test.sig`}\\
\hline
\multicolumn{4}{l}{$^{***}p<0.001$, $^{**}p<0.01$, $^*p<0.05$}\\
\end{tabular}
\end{center}
\end{table}
[^2]:おそらく、他の表もlatex形式で統一した方が良さそう。若干、表のタイトルの具合とか違うし。
# 最後に
こんな感じで、論文執筆のために必要なテクニックをおおよそ使用して、本稿を執筆してきた。確かに、「文章ソフト」としては使いにくいかもしれないが、分析に必要なR Studio内で文章が書け、文章と分析内容が融合しているのは本当に良い。特に、複数のソフトを行き来しなくて良いというのは助かる。ますますRへの愛が高まる。
# 参考文献{-}
田中太郎,2019,「これは架空の書籍」『魔法の国学会』19: 20-34.
Taro Tanaka, 2019, "This is an imarginary book", *Magic Country Association* 19: 20-34.
時代語り男,2019,「令和時代における平成と昭和の交差点:大正時代からのアプローチ」『明治時代学会』30: 20-10.
統計言語好き,2018,「PythonとRの融合:C++で自作関数を作ってみた」『統計モデル・機械学習学会』 4012: 20-30.
結果