微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何使用 vctrs 将自定义格式应用于 tibble 列表列?

如何解决如何使用 vctrs 将自定义格式应用于 tibble 列表列?

我正在使用 vctrs 创建一个新的 new_list_of() S3 类,但是在 tibbles 中使用时我找不到控制此类打印的方法。这是一个使用玩具“fruit_bowl”类的最小示例。理想情况下,我希望列显示 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","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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。