ftExtraでもっとflextable

Tokyo.R 84

Atusy

2020-4-4

Atusy

  • R Markdown関係のコミッタ
  • 去年はfelpパッケージのLTした
    • 後にCRANに登録
  • RStudio PBCを面接落ち
  • データサイエンティスト
    @ HACARUS Inc.
  • blog.atusy.net
  • @Atsushi776

わさびさんやくろきちさんと、
定期的なもくもく会あたりから始めます

R Markdownにおける表組み

Word/パワポで凝った表組みするなら
flextableパッケージが唯一の選択肢
ただし使いやすくはない

install.packages('ftExtra')

パッケージ比較

Package

HTML

PDF

Docx

Pptx

knitr

o

o

o

o

xtable

o

o

x

x

rstudio/gt

o

o

x

x

flextable

o

x

o

o

  • 画像化を許せばxは消える
  • HTML向けにばformattable, reactable, DTなども

knitr::kable()

  • デファクトスタンダード
  • 書式はフォーマット依存
    • HTMLならCSS・PDFならLaTeX・Wordならスタイルなど、 出力に合わせて学ぶことが増える
  • セル結合などはできない
    • HTML/PDF限定ならkableExtraパッケージがある
  • 全角文字の右寄せにバグあり
    • Pandoc由来

xtable・rstudio/gt

  • HTML・PDFにしか使えない
  • rstudio/gtは使いやすいがCRANに来る気配がない

flextable

  • Docx・Pptxで凝ったことやるなら唯一の選択肢
  • 最近bookdownで相互参照できるようにした
  • flex過ぎて使い辛い

ftExtraで文字修飾

マークダウン♡

tibble::tibble(
  x = '***ft^Extra^***', y = 'is *Cool*'
) %>%
  ftExtra::as_flextable() %>%
  ftExtra::colformat_md()

x

y

ftExtra

is Cool

flextableで文字修飾

tibble::tibble(x = 'ftExtra', y = 'is Cool') %>%
  flextable::flextable() %>%
  flextable::compose(
    1, 'x',
    flextable::as_paragraph(
      'ft', flextable::as_sup('Extra')
    )
  ) %>%
  flextable::bold(1, 'x') %>%
  flextable::italic(j = c('x', 'y'))

x

y

ftExtra

is Cool

stringrとの組み合わせが便利!

tibble::tibble(酸化物 = c('SiO2', 'Al2O3'), 
               紅柱石 = c(37.08, 69.92)) %>%
  dplyr::mutate_at(
    '酸化物', stringr::str_replace_all,
    '([:number:]+)', '~\\1~'
  ) %>%
  ftExtra::as_flextable() %>%
  ftExtra::colformat_md()

酸化物

紅柱石

SiO2

37.08

Al2O3

69.92

ftExtraで行をグルーピング

前準備

grouped_iris <- 
  iris[c(1:2, 51:52), 3:5] %>%
  dplyr::group_by(Species)

グループをタイトル化

ftExtra::as_flextable(
  grouped_iris
  # "Species: " を消すには hide_grouplabel = TRUE
)

Petal.Length

Petal.Width

Species: setosa

1.4

0.2

1.4

0.2

Species: versicolor

4.7

1.4

4.5

1.5

グループのセルを結合

ftExtra::as_flextable(
  grouped_iris, groups_to = 'merged'
)

Species

Petal.Length

Petal.Width

setosa

1.4

0.2

1.4

0.2

versicolor

4.7

1.4

4.5

1.5

flextableでグループをタイトル化

できるだけtidyverseを使いたいところ

iris[c(1:2, 51:52), 3:5] %>%
  flextable::as_grouped_data('Species') %>%
  flextable::as_flextable()

Petal.Length

Petal.Width

Species: setosa

1.4

0.2

1.4

0.2

Species: versicolor

4.7

1.4

4.5

1.5

flextableでグループを結合

iris[c(1:2, 51:52), 3:5] %>%
  dplyr::select(Species, everything()) %>%
  flextable::as_flextable() %>%
  flextable::merge_v('Species') %>%
  flextable::theme_vanilla() %>% # テーマの再設定
  flextable::fix_border_issues() # 枠線の修復

Species

Petal.Length

Petal.Width

setosa

1.4

0.2

1.4

0.2

versicolor

4.7

1.4

4.5

1.5

ftExtraでヘッダを階層化

基本はseparate_header

iris[1:3, ] %>%
  ftExtra::as_flextable() %>%
  ftExtra::separate_header(sep = '\\.')

Sepal

Sepal

Petal

Petal

Species

Length

Width

Length

Width

5.1

3.5

1.4

0.2

setosa

4.9

3.0

1.4

0.2

setosa

4.7

3.2

1.3

0.2

setosa

結合もするにはspan_header

iris[1:3, ] %>%
  ftExtra::as_flextable() %>%
  ftExtra::span_header(sep = '\\.')

Sepal

Petal

Species

Length

Width

Length

Width

5.1

3.5

1.4

0.2

setosa

4.9

3.0

1.4

0.2

setosa

4.7

3.2

1.3

0.2

setosa

flextableで見出しを階層化

# 見出しの階層性を表現するデータフレームを容易
header <- tibble::tibble(key = names(iris)) %>%
  tidyr::separate('key', into = c('level1', 'level2'), remove = FALSE)

flextable::flextable(iris[1:3, ]) %>%
  flextable::set_header_df(
    # 事前に準備した見出しをマッピング
    mapping = header, key = 'key'
  ) %>%
  flextable::theme_booktabs() %>%
  flextable::fix_border_issues()

Sepal

Sepal

Petal

Petal

Species

Length

Width

Length

Width

5.1

3.5

1.4

0.2

setosa

4.9

3.0

1.4

0.2

setosa

4.7

3.2

1.3

0.2

setosa

Enjoy & Help Me!

  • Stars
  • Issues
  • PRs
  • Sponsors

https://github.com/atusy/ftExtra