Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
6
Help us understand the problem. What is going on with this article?
@stkdev

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

More than 1 year has passed since last update.

R Markdownで資料作成する

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

全体設定

テーマ変更

R Studioを使ってR Markdownを新規作成します。
image.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のものが内部で使われているようで、

Valid themes include "default", "cerulean", "journal", "flatly", "readable", "spacelab", "united", "cosmo", "lumen", "paper", "sandstone", "simplex", and "yeti".

が指定できます。
image.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

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

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

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

```{r comment=NA}
cat("- データ数: `r nrow(data)` x `r ncol(data)`")
``'


image.png

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

また、表を出力したい場合はknitr::kable()を使うとマークダウンで出力されます
image.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

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

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

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

[タイトル](リンク先)がリンクの書式なので、以下のように展開されます。
image.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

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

6
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
stkdev
naviplus
ECサイト・コンテンツサイト向けのサイト内検索エンジン、レコメンドエンジン、レビュー投稿エンジンや離脱したユーザへのフォローメール配信クラウドサービス(SaaS)を提供する会社。サイトの活性化・売上拡大・運用効率化を実現する総合ソリューションを提供しています。

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
6
Help us understand the problem. What is going on with this article?