如何使用 vctrs 将自定义格式应用于 tibble 列表列?
How can I apply custom-formatting to tibble list-columns using vctrs?
我正在使用 new_list_of()
创建一个新的 vctrs
S3 class,但是当我在 tibbles 中使用时,我找不到控制此 class 打印的方法.这是一个使用玩具“fruit_bowl
”class 的最小示例。理想情况下,我希望列显示 obj_print_data.fruit_bowl()
的输出,即 "2 types of fruit"
和 "1 type of fruit"
,但似乎唯一会打印的是向量的长度。
library(vctrs)
library(tibble)
#>
#> Attaching package: 'tibble'
#> The following object is masked from 'package:vctrs':
#>
#> data_frame
# Fruit bowl constructor function that uses `new_list_of`
fruit_bowl <- function(...) {
x <- list(...)
x <- lapply(x, vec_cast, character())
new_list_of(x, ptype = character(), class = "fruit_bowl")
}
# Set the ptypes for nice printing
vec_ptype_full.fruit_bowl <- function(x, ...) "fruit_bowl"
vec_ptype_abbr.fruit_bowl <- function(x, ...) "frt_bwl"
# Formatting for fruit bowls
format.fruit_bowl <- function(x, ...) {
format_fruits <- function(x) {
n <- length(unique(x))
sprintf("%d type%s of fruit", n, if (n == 1) "" else "s")
}
vapply(x, format_fruits, character(1))
}
# Printing for fruit bowls - use the 'format' function
obj_print_data.fruit_bowl <- function(x, ...) {
if (length(x) == 0) {
return()
}
print(format(x))
}
# Printing works nicely in isolation
fruit_bowl(c("banana", "apple"), "pear")
#> <fruit_bowl[2]>
#> [1] "2 types of fruit" "1 type of fruit"
# ...But not within tibbles
tibble(fruit_bowls = fruit_bowl(c("banana", "apple"), "pear"))
#> # A tibble: 2 x 1
#> fruit_bowls
#> <frt_bwl>
#> 1 [2]
#> 2 [1]
由 reprex package (v0.3.0)
于 2021 年 4 月 10 日创建
我在没有完整阅读文档的情况下就跳枪发布了这个问题。这是概述的正确方法 here
pillar_shaft.fruit_bowl <- function(x, ...) {
pillar::new_pillar_shaft_simple(format(x))
}
tibble(fruit_bowls = fruit_bowl(c("banana", "apple"), "pear"))
#> # A tibble: 2 x 1
#> fruit_bowls
#> <frt_bwl>
#> 1 2 types of fruit
#> 2 1 type of fruit
我正在使用 new_list_of()
创建一个新的 vctrs
S3 class,但是当我在 tibbles 中使用时,我找不到控制此 class 打印的方法.这是一个使用玩具“fruit_bowl
”class 的最小示例。理想情况下,我希望列显示 obj_print_data.fruit_bowl()
的输出,即 "2 types of fruit"
和 "1 type of fruit"
,但似乎唯一会打印的是向量的长度。
library(vctrs)
library(tibble)
#>
#> Attaching package: 'tibble'
#> The following object is masked from 'package:vctrs':
#>
#> data_frame
# Fruit bowl constructor function that uses `new_list_of`
fruit_bowl <- function(...) {
x <- list(...)
x <- lapply(x, vec_cast, character())
new_list_of(x, ptype = character(), class = "fruit_bowl")
}
# Set the ptypes for nice printing
vec_ptype_full.fruit_bowl <- function(x, ...) "fruit_bowl"
vec_ptype_abbr.fruit_bowl <- function(x, ...) "frt_bwl"
# Formatting for fruit bowls
format.fruit_bowl <- function(x, ...) {
format_fruits <- function(x) {
n <- length(unique(x))
sprintf("%d type%s of fruit", n, if (n == 1) "" else "s")
}
vapply(x, format_fruits, character(1))
}
# Printing for fruit bowls - use the 'format' function
obj_print_data.fruit_bowl <- function(x, ...) {
if (length(x) == 0) {
return()
}
print(format(x))
}
# Printing works nicely in isolation
fruit_bowl(c("banana", "apple"), "pear")
#> <fruit_bowl[2]>
#> [1] "2 types of fruit" "1 type of fruit"
# ...But not within tibbles
tibble(fruit_bowls = fruit_bowl(c("banana", "apple"), "pear"))
#> # A tibble: 2 x 1
#> fruit_bowls
#> <frt_bwl>
#> 1 [2]
#> 2 [1]
由 reprex package (v0.3.0)
于 2021 年 4 月 10 日创建我在没有完整阅读文档的情况下就跳枪发布了这个问题。这是概述的正确方法 here
pillar_shaft.fruit_bowl <- function(x, ...) {
pillar::new_pillar_shaft_simple(format(x))
}
tibble(fruit_bowls = fruit_bowl(c("banana", "apple"), "pear"))
#> # A tibble: 2 x 1
#> fruit_bowls
#> <frt_bwl>
#> 1 2 types of fruit
#> 2 1 type of fruit