R MarkdownでコードからMarkdown生成するTips

# R Markdownで資料作成する
何かしらのデータの中身をざっくり調べて、資料化したいとき、R Markdownを使うと便利です。
その時に使えるちょっとしたTipsをメモしておきます。

# 全体設定
## テーマ変更
R Studioを使ってR Markdownを新規作成します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/83530/248925bd-60bb-5635-28a2-5ead8e0cb7fb.png)

最初に生成されるテンプレートの一番上にこういう記述があります。

```
---
title: "Untitled"
output: html_document
---
```

このoutputの部分に設定を追加することで出力形式を変えたり、出力時のテーマを変えたりできます。

```
---
title: "データ確認R Markdown"
output: 
  html_document:
    toc: true
    toc_depth: 2
    toc_float: true
    number_section: true
    theme: cerulean
--
```

`toc`で目次を出したり、`number_section`で章番号をつけたり、`theme`で全体のテンプレートを変えたりできます。
themeは[Bootswatch](https://bootswatch.com/3/)のものが内部で使われているようで、
>  Valid themes include "default", "cerulean", "journal", "flatly", "readable",  "spacelab", "united", "cosmo", "lumen", "paper", "sandstone", "simplex", and "yeti".

が指定できます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/83530/71c9b788-b255-23eb-5445-ad68a94ec08d.png)

`theme: cerulean`を指定したところ、こんな感じの目次が生成されて、色も青っぽくなりました。

## チャンク設定
チャンクのデフォルト設定を変更することができます。
例えば、ソースコードも含めて資料化したい場合は`echo=T`を、ソースコードは基本出さないという場合は`echo=F`を指定しておくと便利です。

```
knitr::opts_chunk$set(echo = F)
```

# Markdown生成
## マークダウン内にRの結果を埋め込む
R Markdownのシンプルな書き方はチャンクの中にRのコードを書くと、結果が出るというもの。

※Qiita上で```を書くとコードとして扱われるため、最後の一つをシングルクオートに変えていますので、コピペの際は注意

```
```{r}
head(data, 1)
``'
```
↓
![image.png](https://qiita-image-store.s3.amazonaws.com/0/83530/3656bcad-d7c1-9e99-66d5-e478d609660f.png)

この場合、マークダウンの文章とは別に結果が表示されます。
マークダウンの文章中に結果を埋め込みたい場合は '`r `'という１行の書き方にすると可能です。

例えば、こういう書き方をすると、

```
- 入力ファイル：sample.csv
- データ数： `r nrow(data)` x `r ncol(data)`

```{r comment=NA}
cat("- データ数： `r nrow(data)` x `r ncol(data)`")
``'
```
↓
![image.png](https://qiita-image-store.s3.amazonaws.com/0/83530/7a733bb7-2f81-21d5-c9a2-9a291979a186.png)

'`r nrow(data)`'というように書いたところはマークダウンに展開されて結果が出力され、下側の`cat()`で出力しているところはあくまでRの処理結果として出力された文字列が生成されます。

また、表を出力したい場合は`knitr::kable()`を使うとマークダウンで出力されます
![image.png](https://qiita-image-store.s3.amazonaws.com/0/83530/db19bdf1-5555-040b-5833-4eac381203c0.png)

## テキストをマークダウンとして出力

プログラムでマークダウンを生成して出力したい場合、`knit_expand()`を使うと可能です。
'`r paste(knit_expand(text = out), collapse = '\n')`'のような感じで`text = "文字列"`を指定し、pasteで出力します。

```
```{r}
out <- c("- hoge","- fuga")
``'

`r paste(knit_expand(text = out), collapse = '\n')`
```
↓
![image.png](https://qiita-image-store.s3.amazonaws.com/0/83530/a1ae1b15-740f-19fb-5553-7b2f56810c4d.png)

さらに、変数を埋め込むことも可能です。`{{ }}`で名前をつけておいて、`knit_expand()`の第２引数以降に指定すると埋め込むことが可能です。

```
```{r}
moji <- "文字"
out <- c("- 箇条書き１",
         "- 箇条書き２", 
         paste0("- ", moji), # 単に変数を展開さすこともできる
         paste0("- [{{hoge}}]({{fuga}})")) # 後で埋め込む変数名を定義
``'

`r paste(knit_expand(text = out, hoge="Googleリンク", fuga="http://www.google.co.jp"), collapse = '\n')`

```

`[タイトル](リンク先)`がリンクの書式なので、以下のように展開されます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/83530/fef69fdf-ef93-39fc-47e4-a99dba39c9aa.png)

## 応用
これらを応用して、データフレームを列ごとに調査してMarkdownにまとめる、ということをやってみます。
少しややこしいですが、列ごとに型を調べ、数値型なら四分位を、factor型なら集計結果を算出して、章立てを構成するということをやってみます。

サンプルデータも貼り付けてるので長いです。
※例のごとくチャンクの終わりの```は最後の一つを'にしています

```
# さくっとデータ確認

R Markdownでデータ確認内容をまとめる際のTips集です。

- ここはふつうのMarkdown
    - 箇条書き
    - hoge


## データ読み込みと型変換
```{r}
data <- data.frame(
  "日付YMD"=c("2018/02/01","2018/02/02","2018/02/09","2018/02/10","2018/02/11","2018/02/18","2018/02/20","2018/02/21","2018/02/22","2018/02/24","2018/02/25","2018/02/26","2018/03/07","2018/03/08","2018/03/09","2018/03/10","2018/03/11","2018/03/12","2018/03/14","2018/03/15","2018/03/16","2018/03/17","2018/03/18","2018/03/19","2018/03/20","2018/03/24","2018/03/25","2018/03/27","2018/03/28","2018/03/29","2018/03/30","2018/03/31","2018/04/01","2018/04/02"),
"日付YMDHMS"=c("2018/01/15 12:12:00","2018/01/16 12:12:00","2018/01/23 12:12:00","2018/01/24 12:12:00","2018/01/25 12:12:00","2018/02/01 12:12:00","2018/02/03 12:12:00","2018/02/04 12:12:00","2018/02/05 12:12:00","2018/02/07 12:12:00","2018/02/08 12:12:00","2018/02/09 12:12:00","2018/02/18 12:12:00","2018/02/19 12:12:00","2018/02/20 12:12:00","2018/02/21 12:12:00","2018/02/22 12:12:00","2018/02/23 12:12:00","2018/02/25 12:12:00","2018/02/26 12:12:00","2018/02/27 12:12:00","2018/02/28 12:12:00","2018/03/01 12:12:00","2018/03/02 12:12:00","2018/03/03 12:12:00","2018/03/07 12:12:00","2018/03/08 12:12:00","2018/03/10 12:12:00","2018/03/11 12:12:00","2018/03/12 12:12:00","2018/03/13 12:12:00","2018/03/14 12:12:00","2018/03/15 12:12:00","2018/03/16 12:12:00"),
"数字"=c(1.005418711,-0.678388247,1.304724134,-0.505765604,0.922991683,0.840653049,0.457446012,-0.6683536,0.275588407,-0.72649637,-0.752952974,-0.279135363,-0.279816282,-1.063173358,0.497759081,-0.15509664,0.961377702,0.621827645,2.149482626,0.608389865,1.685698082,1.072128114,1.725331574,0.973425877,-1.32760823,2.391989691,-0.937037714,2.137561967,1.852441953,-0.411203065,1.282303024,1.275440471,-1.067788693,-1.265772412),
"カテゴリ"=c("A","A","A","A","A","A","A","A","A","A","B","B","C","C","C","C","C","C","C","C","C","C","C","C","C","D","E","E","E","E","E","E","E","E"),
"文字"=c("学習デ","という","だけデ","学習デ","ていき","タを使","クにな","を決め","て何日","ぐらい","う応用","まうと","ータ貯","いう応","。1年","習デー","まらな","かを学","を予測","それだ","という","ないと","どの","を予測","のデー","使って","どの","応用し","を学習","めてい","まうと","決めて","先を予","タを使"),
"時系列"=c(-0.239960181,-0.717208315,-0.581798577,-0.499899009,-0.497580065,-0.302588978,-0.592474074,-0.999182116,-0.528313479,-0.195930277,-0.589054216,-0.530858236,-0.286202981,-0.38340551,-0.23803448,0.141907181,0.28102854,0.213004386,-0.204558427,-0.437323025,-0.769930558,-1.044455817,-0.869149268,-1.26702972,-1.042433517,-0.63207571,-0.983444224,-0.971029176,-1.054820843,-1.031256202,-1.440652867,-1.246845769,-1.260898147,-1.555620586)
)

``'

```{r ,echo=T, comment=NA}
data$`日付YMD` <- as.Date(data$`日付YMD`)
data$`日付YMDHMS` <- as.POSIXlt(data$`日付YMDHMS`)
data$`時系列` <- ts(data$`時系列`)
``'

## 全体の俯瞰

- 入力ファイル：hoge.csv
- データ数： `r nrow(data)` x `r ncol(data)`

### 表の生成
- 横
```{r}
kable(head(data, 1))
``'

- 縦
```{r}
# magrittr
head(data, 1) %>% t %>% kable
``'


```{r}
### 関数定義いろいろ ###

# tableにパーセント表記を追加
table.per <- function(d){
  count <- table(d)
  percent <- round(prop.table(count) * 100,2)
  ret <- data.frame("name"=names(count),
                    "count"=as.numeric(count),
                    "percent"=as.numeric(percent))
  ret
}

# numeric型の場合の処理
md_numeric <- function(d){
  kable(summary(d) %>% c %>% t)
}

# ts型の場合の処理
md_ts <- function(d){
  c("- ", paste(c("Start","End","Frequency"),tsp(d),sep=": "))
}

# Date型の場合の処理
md_date <- function(d){
  d.sorted <- sort(d)
  paste0("- From - To:: ", d.sorted[1], " ～ ", rev(d.sorted)[1])
}

# factor型の場合の処理
md_factor <- function(d){
  uniq <- unique(d)
  ret <- paste0("- ユニーク要素数:: ", length(uniq), '\n')
  if(length(uniq) < 10){
    tbl <- table.per(d)
    ret <- c(ret, tbl %>% kable, '\n')
  }
  ret
}

``'


```{r}
out <- "## 一列ずつ要素の確認"
out <- c(out, "列ごとに処理を行い、結果を出力します\n")

for(col in names(data)){
  d <- data[,col]
  cls <- class(d)[1]
  
  out <- c(out, paste0("### ", col, "(", cls, "型)", '\n'))

  # 型により処理分岐
  if("numeric" %in% cls){
    md_func <- md_numeric
  }else if("ts" %in% cls){
    md_func <- md_ts
  }else if(0 < sum(c("Date","POSIXlt") %in% cls)){
    md_func <- md_date
  }else{
    md_func <- md_factor
  }
  out <- c(out, md_func(d), '\n')
}

``'

`r paste(knit_expand(text = out), collapse = '\n')`
```

結果

![image.png](https://qiita-image-store.s3.amazonaws.com/0/83530/a9fccc0b-92a2-08f7-4f5b-0ad439b60582.png)

これはもう少しちゃんと関数化して、データフレームを放り込めば、きれいに出力されるようにすれば使いやすくなるかも。
あと、グラフを挿入するのはまだわからないので、まだまだ改善の余地はありそうです。