library(pillar)
"tbl"
サブクラスの印刷出力をカスタマイズする方法は? この vignette では、さまざまなカスタマイズオプションを紹介している。 tibble内のベクタクラスの書式のカスタマイズは、以下で説明する。 vignette("pillar ", package =" vctrs")
. 制御とデータの流れの概要は、vignette("printing")
に示されている。
この vignette は、読者がS3のクラス、メソッド、および継承に精通していることを想定している。 は、その “S3” chapter of Hadley Wickham’s" アドバンスドR "は良いスタートである。
pillarの表示機能を利用するには、tibble(クラス "tbl_df"
と "tbl"
)、dbplyr遅延テーブル( "tbl_lazy"
と "tbl"
)、sf空間データフレーム( "sf"
, "tbl_df"
と "tbl"
)のように "tbl"
を継承したクラスを作成してみよう。 様々なカスタマイズのオプションを提示しているので、任意のサブクラスでデータフレームの例のコンストラクタを作成する。
<- function(class) {
example_tbl ::new_data_frame(
vctrslist(
a = letters[1:3],
b = data.frame(c = 1:3, d = 4:6 + 0.5)
),class = c(class, "tbl")
) }
"default"
クラスは、まだ何のカスタマイズもされておらず、通常の tibble のように表示される。
example_tbl("default")
#> $a
#> [1] "a" "b" "c"
#>
#> $b
#> c d
#> 1 1 4.5
#> 2 2 5.5
#> 3 3 6.5
#>
#> attr(,"class")
#> [1] "default" "tbl" "data.frame"
最も簡単なカスタマイズは、ヘッダーを調整することである。 ヘッダーに表示される情報を、元の書式を維持したまま拡張または置換する tbl_sum()
メソッドを実装する。
<- function(x, ...) {
tbl_sum.default_header_extend <- NextMethod()
default_header c(default_header, "New" = "A new header")
}
example_tbl("default_header_extend")
#> # A data frame: 3 × 2
#> # New: A new header
#> a b$c $d
#> <chr> <int> <dbl>
#> 1 a 1 4.5
#> 2 b 2 5.5
#> 3 c 3 6.5
<- function(x, ...) {
tbl_sum.default_header_replace c("Override" = "Replace all headers")
}
example_tbl("default_header_replace")
#> # Override: Replace all headers
#> a b$c $d
#> <chr> <int> <dbl>
#> 1 a 1 4.5
#> 2 b 2 5.5
#> 3 c 3 6.5
ヘッダーのスタイルを変更するには、tbl_format_header()
メソッドを実装する。 実装は、先頭のハッシュを含む全体のフォーマットとスタイリングに責任を持つ。
<- function(x, setup, ...) {
tbl_format_header.custom_header_replace ::style_italic(names(setup$tbl_sum), " = ", setup$tbl_sum)
cli
}
example_tbl("custom_header_replace")
#> A data frame = 3 × 2
#> a b$c $d
#> <chr> <int> <dbl>
#> 1 a 1 4.5
#> 2 b 2 5.5
#> 3 c 3 6.5
汎用的な ctl_new_rowid_pillar()
を実装することで、行ID列の表示をカスタマイズすることができる。アラビア数字の代わりにローマ数字を表示すには、utils::as.roman()
を使って対応するシーケンスを生成し、先に紹介したように new_pillar()
と関連するメソッドを使って行 ID の柱を構築することができる。
<- function(controller, x, width, ...) {
ctl_new_rowid_pillar.pillar_roman <- NextMethod()
out <- utils::as.roman(seq_len(nrow(x)))
rowid <- max(nchar(as.character(rowid)))
width new_pillar(
list(
title = out$title,
type = out$type,
data = pillar_component(
new_pillar_shaft(list(row_ids = rowid),
width = width,
class = "pillar_rif_shaft"
)
)
),width = width
)
}
example_tbl("pillar_roman")
#> # A data frame: 3 × 2
#> a b$c $d
#> <chr> <int> <dbl>
#> I a 1 4.5
#> II b 2 5.5
#> III c 3 6.5
柱はコンポーネントで構成されており、詳細は ?new_pillar_component
を参照。 ctl_new_pillar()
メソッドを拡張またはオーバーライドして、外観を変更する。 以下の例では、出力に一定幅の表罫線を追加している。
<- function(controller, x, width, ..., title = NULL) {
ctl_new_pillar.pillar_rule <- NextMethod()
out new_pillar(list(
top_rule = new_pillar_component(list("========"), width = 8),
title = out$title,
type = out$type,
mid_rule = new_pillar_component(list("--------"), width = 8),
data = out$data,
bottom_rule = new_pillar_component(list("========"), width = 8)
))
}
example_tbl("pillar_rule")
#> # A data frame: 3 × 2
#> ======== ======== ========
#> a b$c $d
#> <chr> <int> <dbl>
#> -------- -------- --------
#> 1 a 1 4.5
#> 2 b 2 5.5
#> 3 c 3 6.5
#> ======== ======== ========
幅を適応させるために、あらかじめ指定された幅に罫線を整形する format()
メソッドを持つ "rule"
クラスを実装している。
<- function(char = "-") {
rule stopifnot(nchar(char) == 1)
structure(char, class = "rule")
}
<- function(x, width, ...) {
format.rule paste(rep(x, width), collapse = "")
}
<- function(controller, x, width, ..., title = NULL) {
ctl_new_pillar.pillar_rule_adaptive <- NextMethod()
out if (is.null(out)) {
return(NULL)
}
new_pillar(list(
top_rule = new_pillar_component(list(rule("=")), width = 1),
title = out$title,
type = out$type,
mid_rule = new_pillar_component(list(rule("-")), width = 1),
data = out$data,
bottom_rule = new_pillar_component(list(rule("=")), width = 1)
))
}
example_tbl("pillar_rule_adaptive")
#> # A data frame: 3 × 2
#> = = =
#> a b$c $d
#> <chr> <int> <dbl>
#> - - -
#> 1 a 1 4.5
#> 2 b 2 5.5
#> 3 c 3 6.5
#> = = =
複合柱は、データフレーム、行列、配列を含む列に対して ctl_new_pillar_list()
で作成される。 デフォルトの実装では、上に示した ctl_new_pillar()
も呼び出される。 この(やや人工的な)例では、データフレームの列をすべて隠して、型が "<hidden>"
.
<- function(controller, x, width, ..., title = NULL) {
ctl_new_pillar_list.hide_df if (!is.data.frame(x)) {
return(NextMethod())
}
if (width < 8) {
return(NULL)
}
list(new_pillar(
list(
title = pillar_component(new_pillar_title(title)),
type = new_pillar_component(list("<hidden>"), width = 8),
data = new_pillar_component(list(""), width = 1)
),width = 8
))
}
example_tbl("hide_df")
#> # A data frame: 3 × 2
#> <hidden>
#>
#> 1 <hidden>
#> 2
#> 3 <hidden>
最後になったが、tbl_format_body()
をオーバーライドすることで、ボディの表示を完全に変更することも可能である。 以下の例では、 tibble にプレーンデータフレーム出力を使用している。
<- function(x, setup, ...) {
tbl_format_body.oldskool capture.output(print.data.frame(setup$df))
}
print(example_tbl("oldskool"), n = 2)
#> # A data frame: 3 × 2
#> a b.c b.d
#> 1 a 1 4.5
#> 2 b 2 5.5
#> # … with 1 more row
なお、デフォルトの表示出力は tbl_format_setup()
で計算されるため、かなりの時間がかかる。 どうしても本体全体の出力を変更する必要がある場合は、独自の tbl_format_setup()
メソッドを用意することを検討してみよう。