打印 tibble 以控制台消息

printing tibble to console with a message

如何将小标题连同消息一起打印到控制台? 我想编写一个函数,它输出一个 tibble 以及一条包含有关该 tibble 的性质的一些信息的详细消息。

这是一个非常简单的例子,说明了我的想法。在第一次尝试中,该功能不起作用。在第二次尝试中,它工作但输出了一些其他不必要的细节。

# libraries needed
library(crayon)
library(tibble)

# writing the function
try.fn1 <- function() {
  # prepare the tibble
  x <- tibble::as.tibble(x = rnorm(1:10))
  # output the associated message to the user of the function
  base::message(
    cat(crayon::blue("The tibble I prepared is-"), x)
    )
  base::message(print(x))
}

# using the function
try.fn1()
#> The tibble I prepared is-
#> Error in cat(crayon::blue("The tibble I prepared is-"), x): argument 2 (type 'list') cannot be handled by 'cat'

# another attempt
try.fn2 <- function() {
  # prepare the tibble
  x <- tibble::as.tibble(x = rnorm(1:10))
  # output the associated message to the user of the function
  base::message(
    cat(crayon::blue("The tibble I prepared is-"))
  )
  base::message(print(x))
}

# using the function
try.fn2()
#> The tibble I prepared is-
#> 
#> # A tibble: 10 x 1
#>       value
#>       <dbl>
#>  1 -0.00529
#>  2  0.562  
#>  3 -0.511  
#>  4 -0.260  
#>  5 -0.232  
#>  6 -1.92   
#>  7 -0.698  
#>  8  2.38   
#>  9  1.59   
#> 10 -0.585
#> c(-0.00528727617885923, 0.56168758575177, -0.510982641120654, -0.260458372988822, -0.231847890601322, -1.91514178853023, -0.697661618989503, 2.37722341810185, 1.5869372625472, -0.584576993642516)

reprex package (v0.2.0) 创建于 2018-03-15。

捕获标准输出,这是 cat()print() 发送输出的地方,然后连接并传递给消息:

message(paste(capture.output({
  cat(crayon::blue("The tibble I prepared is-\n"))
  print(x)
}), collapse = "\n"))

我建议您 使用 模仿 来自 tibble 的未导出 print 函数中的代码。要访问未导出的函数,请使用 triple-colons 访问 tibble:::print.tbl_df(和 .tbl)。

查找这些函数需要知道的两件事:

  1. R 中的许多函数根据在它们中调用的对象而具有不同的行为(甚至不同的参数)。例如,如果给定一个 lm 对象,summary 的行为会有所不同,一个 matrix, etc. To see all of the differentsummaryfunctions, trymethods(summary)`。 (可以在 Hadley 的 Advanced R 在线书籍中找到一个很好的参考资料,称为 "S3",可以了解更多关于此的信息。)

    如果你把它带到这个问题上,运行 methods("print") 提出(除其他外):

    m <- methods("print")
    m[ grepl("tbl|frame",m) ]
    # [1] "print.data.frame" "print.frame"      "print.tbl_cube"   "print.tbl_df"    
    # [5] "print.tbl_lazy"   "print.tbl_sql"   
    

    这些不必由各自的包 导出 即可提供给 R。事实上,我似乎发现其中有更多未导出。事实上 print(my_new_object) 只是简单地 有效 可以为新用户和有经验的用户带来巨大的便利。

  2. 你总能在网上找到这个函数的源码(比如在 GitHub 上,比如这个源码 here),但这并不总是很方便,如果你不小心,它可能是你安装的包版本以外的版本。

    R 中的大多数对象都可以通过在控制台上键入名称来检查(深度或其他方式)。这对变量和函数一样有效。看函数的三种方式:

    1. library(pkgname)require(pkgname)之后,直接输入函数名即可。这就是大多数人学习和使用 R 的方式。

    2. 即使在使用 libraryrequire 加载包之前,您也可以使用 double-colons 查看任何包的功能,例如 dplyr::filter。这在包之间共享函数名称(可能 "masking" 或冲突)时也很有用,并且您想清楚要使用哪个。

    3. 如果一个函数没有被导出,不管你是否调用了library,你都只能通过triple-colons访问它,比如tibble:::print.tbl_df. (事实上​​ ,有一些方法可以查看没有冒号的源代码,例如 R 的 browser,但这在这里并不重要。)

使用未导出的函数存在风险。它们通常由于多种原因之一而未导出,包括最重要的 (a) 不是包功能的核心,以及 (b) 作者不需要或无意维护该功能的 API(参数,输出)在发布之间。未导出的函数可能会(并且经常发生)消失、显着更改参数或更改方法。本质上,作者已经投资于在导出函数上保持某种表面上的一致性,而不是未导出的函数。

因此,建议您查看或使用 tibble:::print.tbl_df 是有风险的:他们可能会更改或删除该功能。话虽如此,print.* 函数通常不会被导出,因为它们只能用于通用 S3 版本 print。我希望这个特定功能发生变化的唯一原因是作者是否更改了程序包使用的对象的拼写或类型。而且我认为这种情况不会很快发生。