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

kable output is suboptimal for data.tables with list columns that contain functions #2075

Closed
sebffischer opened this issue Nov 17, 2021 · 9 comments
Labels
feature Feature requests won't fix Won't fix due to lack of time/interest or there exist workarounds

Comments

@sebffischer
Copy link

sebffischer commented Nov 17, 2021

The knitr::kable output is suboptimal for data.tables with list columns that contain functions (see reprex below).

dt = data.table::data.table(list(help))
print(knitr::kable(dt))
#> 
The `knitr::kable()` output is suboptimal for data.tables with list columns that contain functions, see the reprex below. 

#> 
#> |V1                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
#> |:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
#> |function (topic, package = NULL, lib.loc = NULL, verbose = getOption("verbose"), ,     try.all.packages = getOption("help.try.all.packages"), help_type = getOption("help_type")) , {,     types <- c("text", "html", "pdf"),     help_type <- if (!length(help_type)) ,         "text",     else match.arg(tolower(help_type), types),     if (!missing(package)) ,         if (is.name(y <- substitute(package))) ,             package <- as.character(y),     if (missing(topic)) {,         if (!is.null(package)) {,             if (interactive() && help_type == "html") {,                 port <- tools::startDynamicHelp(NA),                 if (port <= 0L) ,                   return(library(help = package, lib.loc = lib.loc, ,                     character.only = TRUE)),                 browser <- if (.Platform$GUI == "AQUA") {,                   get("aqua.browser", envir = as.environment("tools:RGUI")),                 },                 else getOption("browser"),                 browseURL(paste0("http://127.0.0.1:", port, "/library/", ,                   package, "/html/00Index.html"), browser),                 return(invisible()),             },             else return(library(help = package, lib.loc = lib.loc, ,                 character.only = TRUE)),         },         if (!is.null(lib.loc)) ,             return(library(lib.loc = lib.loc)),         topic <- "help",         package <- "utils",         lib.loc <- .Library,     },     ischar <- tryCatch(is.character(topic) && length(topic) == ,         1L, error = function(e) FALSE),     if (!ischar) {,         reserved <- c("TRUE", "FALSE", "NULL", "Inf", "NaN", ,             "NA", "NA_integer_", "NA_real_", "NA_complex_", "NA_character_"),         stopic <- deparse1(substitute(topic)),         if (!is.name(substitute(topic)) && !stopic %in% reserved) ,             stop("'topic' should be a name, length-one character vector or reserved word"),         topic <- stopic,     },     paths <- index.search(topic, find.package(if (is.null(package)) ,         loadedNamespaces(),     else package, lib.loc, verbose = verbose)),     try.all.packages <- !length(paths) && is.logical(try.all.packages) && ,         !is.na(try.all.packages) && try.all.packages && is.null(package) && ,         is.null(lib.loc),     if (try.all.packages) {,         for (lib in .libPaths()) {,             packages <- .packages(TRUE, lib),             packages <- packages[is.na(match(packages, .packages()))],             paths <- c(paths, index.search(topic, file.path(lib, ,                 packages))),         },         paths <- paths[nzchar(paths)],     },     structure(unique(paths), call = match.call(), topic = topic, ,         tried_all_packages = try.all.packages, type = help_type, ,         class = "help_files_with_topic"), } |

Created on 2021-11-17 by the reprex package (v2.0.1)

@cderv
Copy link
Collaborator

cderv commented Nov 17, 2021

Thanks for the report.

This is not an issue with data.table specifically but with list column in structure that supports it.

> knitr::kable(tibble::tibble(a = list(head)))

|a                                     |
|:-------------------------------------|
|function (x, ...) , UseMethod("head") |

I don't think knitr::kable() was designed for those type of structure.

Printing list column is not something easy to do generically. What should be printed for such cells exactly ?

I don't see a use case where using kable() or any other table formatting tool would be useful. 🤔
Why not just print them as in the console ? which will use the printing method that usually supports it ?

---
title: "Test"
output: html_document
---

```{r}
tibble::tibble(a = list(head))
```

```{r}
data.table::data.table(a = list(head))
```

image

Is that expectation to have a markdown table containing the same information as the console printed version ?

Thanks.

@sebffischer
Copy link
Author

sebffischer commented Nov 17, 2021

Thanks for the quick answer,
I agree that there is probably nothing to print that is particularly useful. Nonetheless
the suggestion you made below is imo a way better default behaviour than is currently implemented.

@cderv
Copy link
Collaborator

cderv commented Nov 17, 2021

the suggestion you made below

Which suggestion exactly ? Just to be sure I got it right.

@sebffischer
Copy link
Author

I understood it as you suggesting to e.g. represent the function head as <function[1]>.
Or maybe simply use the class of the object?

@sebffischer
Copy link
Author

sebffischer commented Nov 17, 2021

Maybe in general something like sprintf("<%s>", class(obj)[1]) ?

@cderv
Copy link
Collaborator

cderv commented Nov 17, 2021

I wanted to confirm that this would be your expectation as a result of a kable() call on such table.

This could be a way to output the content without creating those long unreadable contents. We would need process the table and transform the content before printing it a table. Seems something that could be considered.

I still think that when this happens, one should prevent from using knitr::kable() on table with list column. But maybe I am wrong...

I'll add this as a feature request. Thanks for the suggestion.

I think this is related to rstudio/rmarkdown#1822 (comment) where were paged_table() in rmarkdown kind of detect list content to write a summary and not the content.

@cderv cderv added the feature Feature requests label Nov 17, 2021
@atusy
Copy link
Collaborator

atusy commented Nov 17, 2021

I think the optimal outputs depend on users.
For example, head may become

  • function (x, ...) UseMethod("head")
  • function
  • head
  • function<head>

and so on...

I would rather suggest define own format methods.

format.list = function(x, ...) vapply(x, function(x) class(x)[[1L]], NA_character_)
knitr::kable(tibble::tibble(
  x = list(head, rnorm)
))

@cderv
Copy link
Collaborator

cderv commented Nov 17, 2021

Yes I agree - It is what I meant by "Printing list column is not something easy to do generically. What should be printed for such cells exactly ?" 😄

Regarding format method, that is a nice solution ! thanks for sharing.

@yihui yihui added the won't fix Won't fix due to lack of time/interest or there exist workarounds label Mar 24, 2022
@yihui yihui closed this as completed Mar 24, 2022
@github-actions
Copy link

This old thread has been automatically locked. If you think you have found something related to this, please open a new issue by following the issue guide (https://yihui.org/issue/), and link to this old issue if necessary.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Sep 21, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
feature Feature requests won't fix Won't fix due to lack of time/interest or there exist workarounds
Projects
None yet
Development

No branches or pull requests

4 participants