Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding "paged_df" to a data.frame class stops the data frame from printing to console when {rmarkdown} is loaded #2562

Open
5 tasks done
markfairbanks opened this issue Jul 2, 2024 · 5 comments

Comments

@markfairbanks
Copy link

Adding "paged_df" to a data.frame subclass stops the data frame from printing to console when {rmarkdown} is loaded.

This issue occurs when using library(rmarkdown) but also prevents things from working with the {reprex} package.

This is a new issue, not sure what changed. I found out about it due to this issue here. I add "paged_df" as a subclass of a tidytable found in the print method here so paged printing would work in Rmarkdown. Not sure if there is a better/recommended way to allow paged printing of a data frame subclass like a tidytable?

There's not output here when using reprex::reprex()

library(tidytable)

tidytable(x = 1:3, y = 1:3)

Created on 2024-07-01 with reprex v2.1.0

xfun::session_info('rmarkdown')
#> R version 4.3.1 (2023-06-16)
#> Platform: aarch64-apple-darwin20 (64-bit)
#> Running under: macOS Sonoma 14.5
#> 
#> Locale: en_US.UTF-8 / en_US.UTF-8 / en_US.UTF-8 / C / en_US.UTF-8 / en_US.UTF-8
#> 
#> Package version:
#>   base64enc_0.1.3   bslib_0.7.0       cachem_1.1.0      cli_3.6.3        
#>   digest_0.6.36     evaluate_0.24.0   fastmap_1.2.0     fontawesome_0.5.2
#>   fs_1.6.4          glue_1.7.0.9000   graphics_4.3.1    grDevices_4.3.1  
#>   highr_0.11        htmltools_0.5.8.1 jquerylib_0.1.4   jsonlite_1.8.8   
#>   knitr_1.47        lifecycle_1.0.4   memoise_2.0.1     methods_4.3.1    
#>   mime_0.12         R6_2.5.1          rappdirs_0.3.3    rlang_1.1.4      
#>   rmarkdown_2.27    sass_0.4.9        stats_4.3.1       tinytex_0.51     
#>   tools_4.3.1       utils_4.3.1       xfun_0.45         yaml_2.3.8       
#> 
#> Pandoc version: 3.1.1

Created on 2024-07-01 with reprex v2.1.0

-->

Checklist

When filing a bug report, please check the boxes below to confirm that you have provided us with the information we need. Have you:

  • formatted your issue so it is easier for us to read?

  • included a minimal, self-contained, and reproducible example?

  • pasted the output from xfun::session_info('rmarkdown') in your issue?

  • upgraded all your packages to their latest versions (including your versions of R, the RStudio IDE, and relevant R packages)?

  • installed and tested your bug with the development version of the rmarkdown package using remotes::install_github("rstudio/rmarkdown") ?

@cderv
Copy link
Collaborator

cderv commented Jul 2, 2024

This is a new issue, not sure what changed.

Do you remember when it was working ? Which version of the tools ?

This is really puzzling to me it was working before...

Let's discuss why this is happening.

I believe you get the issue because your print method is returning invisible(x) and so it is not catch by knitr / evaluate output.

The printing does correctly happens, meaning print.page_df for rmarkdown is called, but not used by evaluation.

This all happens in evaluate handlers
https://github.com/yihui/knitr/blob/4a02625e0dce1b88f1c90396790e1eb40401a779/R/utils.R#L863-L881

So using invisible() but also calling print within another print() as you currently do print.tidytable will mess this up I believe.
If you remove invisible(x) in print.tidytable() this works too.

diff --git a/R/print.R b/R/print.R
index d6a3d201..3959cb95 100644
--- a/R/print.R
+++ b/R/print.R
@@ -3,7 +3,6 @@
 print.tidytable <- function(x, ..., n = NULL, width = NULL, n_extra = NULL) {
   y <- set_class(x, print_class("tidytable_print"))
   print(y, ..., n = n, width = width, n_extra = n_extra)
-  invisible(x)
 }

 #' @export

I did a few tests, and this is happening at the evaluate level too

> str(evaluate::evaluate(input = "library(rmarkdown)\nlibrary(tidytable)\ntidytable(x = 1:3, y = 1:3)"))
List of 3
 $ :List of 1
  ..$ src: chr "library(rmarkdown)\n"
  ..- attr(*, "class")= chr "source"
 $ :List of 1
  ..$ src: chr "library(tidytable)\n"
  ..- attr(*, "class")= chr "source"
 $ :List of 1
  ..$ src: chr "tidytable(x = 1:3, y = 1:3)"
  ..- attr(*, "class")= chr "source"

See how there is no result captured when rmarkdown is making the print method available

We have one results showing when no rmarkdown is loaded,

> str(evaluate::evaluate(input = "suppressPackageStartupMessages(library(tidytable))\ntidytable(x = 1:3, y = 1:3)"))
List of 3
 $ :List of 1
  ..$ src: chr "suppressPackageStartupMessages(library(tidytable))\n"
  ..- attr(*, "class")= chr "source"
 $ :List of 1
  ..$ src: chr "tidytable(x = 1:3, y = 1:3)"
  ..- attr(*, "class")= chr "source"
 $ : chr "# A tidytable: 3 × 2\n      x     y\n  <int> <int>\n1     1     1\n2     2     2\n3     3     3\n"

So maybe this is specific to how print.paged_df is working - it is supposed to in evaluation results to be sewed using sew.knit_asis method. 🤔

I am still wondering about this nested print() of object, and how evaluate works.

@yihui you know all this better than me - do you confirm this what is happening when the method defined is

print.tidytable <- function(x, ..., n = NULL, width = NULL, n_extra = NULL) {
  y <- set_class(x, print_class("tidytable_print"))
  print(y, ..., n = n, width = width, n_extra = n_extra)
  invisible(x)
}

and that this is how it work ? Or is there an issue somewhere.

I am surprised this was working before as mentioned .... 🤔

@markfairbanks regarding printing in knitr context, you can have custom knit_print() method too.
You can read more on knit_print() method at https://cran.r-project.org/web/packages/knitr/vignettes/knit_print.html

Not sure if there is a better/recommended way to allow paged printing of a data frame subclass like a tidytable?

rmarkdown::paged_table() is an exported function which is the one handling options and class for paged_df. Usually this can be used to build a pagetable from a dataframe.

Though adding the class is working ok.

@markfairbanks
Copy link
Author

markfairbanks commented Jul 5, 2024

Do you remember when it was working ? Which version of the tools ?

I'm not sure unfortunately. It's been working fine for a few years but broke semi-recently.

You can read more on knit_print() method at

rmarkdown::paged_table() is an exported function which is the one handling options and class for paged_df. Usually this can be used to build a pagetable from a dataframe. Though adding the class is working ok.

I've tried all sorts of things but nothing I do seems to allow me to define the tidytable/data.table subclass that prints a paged table when paged.print = TRUE. I tried permanently attaching "paged_df" as a subclass and it no longer prints normally in console.

Is there a simple way to define "if paged.print = TRUE use paged printing, otherwise use normal print"?

Feel free to close this issue by the way as maybe this is more of a Stack Overflow type question - but if you happen to know what I need to do that'd be great.

@cderv
Copy link
Collaborator

cderv commented Jul 5, 2024

I'll think about this. To understand full context, out of curiosity, why return invisible(x) in your print method ?

@markfairbanks
Copy link
Author

markfairbanks commented Jul 6, 2024

I can't remember to be honest 😅. I think a contributor recommended it and it was part of the hack to get paged printing to work, but it's possible it was unnecessary to add.

Edit: If I remove invisible(x) it doesn't help with this issue - reprex::reprex() still doesn't print anything

@markfairbanks
Copy link
Author

markfairbanks commented Jul 8, 2024

So I reset printing to get back to basics. Essentially I have a data frame which uses printing from pillar (like tibble does) by using "tbl" as a subclass. I do not define a print.tidytable() method anymore. Printing now works properly in console and reprex::reprex() works.

But now paged printing doesn't work.

library(tidytable)

df <- tidytable(x = 1:3, y = c("a", "a", "b"))

df
#> # A tidytable: 3 × 2
#>       x y    
#>   <int> <chr>
#> 1     1 a    
#> 2     2 a    
#> 3     3 b

class(df)
#> [1] "tidytable"  "tbl"        "data.table" "data.frame"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants