通过消息打印到控制台

时间:2018-03-16 03:00:43

标签: r tidyverse tibble

如何将一个tibble打印到控制台并附带消息? 我想编写一个输出一个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。

2 个答案:

答案 0 :(得分:2)

我建议您使用模仿来自print的未导出tibble函数中的代码。要访问未导出的函数,请使用三重冒号访问tibble:::print.tbl_df(以及.tbl)。

要了解这些功能需要了解两件事:

  1. R中的许多函数基于其中调用的对象具有不同的行为(甚至是不同的参数)。例如,如果给定summary个对象,lm摘要matrix, etc. To see all of the different方法(摘要)`,functions, try的行为会有所不同。 (在Hadley的Advanced R在线书籍中可以看到一个很好的参考资料,可以在“{3}”在线书籍中看到更多关于这一点的信息,称为“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。当在包之间共享一个函数名(可能是“屏蔽”或碰撞)时,这也很有用,并且您希望清楚使用哪一个。

    3. 如果未导出某个功能,则无论您是否呼叫library,都只能使用三个冒号访问它,例如tibble:::print.tbl_df。 (实际上,有很多方法可以查看没有冒号的来源,例如在R browser中,但这在这里并不重要。)

  3. 使用未导出的功能存在风险。它们通常由于以下几个原因之一而未被导出,其中最重要的是(a)不是包的功能的核心,(b)作者不需要或不打算在版本之间维护该函数的API(参数,输出)。有可能(经常发生)未导出的函数可能会消失,显着改变参数或更改方法。基本上,作者已经投入了在出口函数上保持一些相似性,而不是未出口函数。

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

答案 1 :(得分:0)

捕获标准输出,即cat()print()发送输出的位置,然后连接并传递给消息:

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