calendar columns break `DT::datatable()`
maxheld83 opened this issue · 4 comments
I expected DT::datatable()
to use a format method (like as.character()
) of a calendar column, and show me that.
But passing a clock calendar column to DT fails.
Manually wrapping as.character()
around the offending column works.
data.frame(cals = clock::year_quarter_day(year = 2000:2001, quarter = 2)) |>
DT::datatable()
#> Error:
#> ! Names must be a character vector.
#> Backtrace:
#> ▆
#> 1. ├─base::tryCatch(...)
#> 2. │ └─base (local) tryCatchList(expr, classes, parentenv, handlers)
#> 3. │ ├─base (local) tryCatchOne(...)
#> 4. │ │ └─base (local) doTryCatch(return(expr), name, parentenv, handler)
#> 5. │ └─base (local) tryCatchList(expr, names[-nh], parentenv, handlers[-nh])
#> 6. │ └─base (local) tryCatchOne(expr, names, parentenv, handlers[[1L]])
#> 7. │ └─base (local) doTryCatch(return(expr), name, parentenv, handler)
#> 8. ├─base::withCallingHandlers(...)
#> 9. ├─base::saveRDS(...)
#> 10. ├─base::do.call(...)
#> 11. ├─base (local) `<fn>`(...)
#> 12. ├─global `<fn>`(input = base::quote("gaudy-geese_reprex.R"))
#> 13. │ └─rmarkdown::render(input, quiet = TRUE, envir = globalenv(), encoding = "UTF-8")
#> 14. │ └─knitr::knit(knit_input, knit_output, envir = envir, quiet = quiet)
#> 15. │ └─knitr:::process_file(text, output)
#> 16. │ ├─base::withCallingHandlers(...)
#> 17. │ ├─knitr:::process_group(group)
#> 18. │ └─knitr:::process_group.block(group)
#> 19. │ └─knitr:::call_block(x)
#> 20. │ └─knitr:::block_exec(params)
#> 21. │ └─knitr:::eng_r(options)
#> 22. │ ├─knitr:::in_input_dir(...)
#> 23. │ │ └─knitr:::in_dir(input_dir(), expr)
#> 24. │ └─knitr (local) evaluate(...)
#> 25. │ └─evaluate::evaluate(...)
#> 26. │ └─evaluate:::evaluate_call(...)
#> 27. │ ├─evaluate (local) handle(...)
#> 28. │ │ └─base::try(f, silent = TRUE)
#> 29. │ │ └─base::tryCatch(...)
#> 30. │ │ └─base (local) tryCatchList(expr, classes, parentenv, handlers)
#> 31. │ │ └─base (local) tryCatchOne(expr, names, parentenv, handlers[[1L]])
#> 32. │ │ └─base (local) doTryCatch(return(expr), name, parentenv, handler)
#> 33. │ ├─base::withCallingHandlers(...)
#> 34. │ ├─base::withVisible(value_fun(ev$value, ev$visible))
#> 35. │ └─knitr (local) value_fun(ev$value, ev$visible)
#> 36. │ └─knitr (local) fun(x, options = options)
#> 37. │ ├─base::withVisible(knit_print(x, ...))
#> 38. │ ├─knitr::knit_print(x, ...)
#> 39. │ └─htmlwidgets:::knit_print.htmlwidget(x, ...)
#> 40. │ ├─knitr::knit_print(...)
#> 41. │ │ └─knitr:::need_screenshot(x, ...)
#> 42. │ └─htmlwidgets:::toHTML(x, standalone = FALSE, knitrOptions = options)
#> 43. │ ├─htmltools::tagList(...)
#> 44. │ │ └─rlang::dots_list(...)
#> 45. │ └─htmlwidgets:::widget_data(x, x$id)
#> 46. │ ├─htmlwidgets:::toJSON(createPayload(x))
#> 47. │ └─htmlwidgets:::createPayload(x)
#> 48. │ └─htmlwidgets::JSEvals(x)
#> 49. │ ├─names(which(unlist(shouldEval(list)))) %||% list()
#> 50. │ ├─base::which(unlist(shouldEval(list)))
#> 51. │ ├─base::unlist(shouldEval(list))
#> 52. │ └─htmlwidgets:::shouldEval(list)
#> 53. │ └─base::lapply(options, shouldEval)
#> 54. │ └─htmlwidgets (local) FUN(X[[i]], ...)
#> 55. │ └─base::lapply(options, shouldEval)
#> 56. │ └─htmlwidgets (local) FUN(X[[i]], ...)
#> 57. │ ├─base::`names<-`(`*tmp*`, value = seq_len(n) - 1L)
#> 58. │ └─clock:::`names<-.clock_rcrd`(`*tmp*`, value = seq_len(n) - 1L)
#> 59. └─rlang (local) `<fn>`("Names must be a character vector.")
Session info
sessioninfo::session_info()
#> ─ Session info ───────────────────────────────────────────────────────────────
#> setting value
#> version R version 4.3.0 (2023-04-21)
#> os macOS Ventura 13.3.1
#> system aarch64, darwin20
#> ui X11
#> language (EN)
#> collate en_US.UTF-8
#> ctype en_US.UTF-8
#> tz Europe/Berlin
#> date 2023-04-25
#> pandoc 3.1.2 @ /opt/homebrew/bin/ (via rmarkdown)
#>
#> ─ Packages ───────────────────────────────────────────────────────────────────
#> package * version date (UTC) lib source
#> bslib 0.4.2 2022-12-16 [1] CRAN (R 4.3.0)
#> cachem 1.0.7 2023-02-24 [1] CRAN (R 4.3.0)
#> cli 3.6.1 2023-03-23 [1] CRAN (R 4.3.0)
#> clock 0.6.1 2022-07-18 [1] CRAN (R 4.3.0)
#> crosstalk 1.2.0 2021-11-04 [1] CRAN (R 4.3.0)
#> digest 0.6.31 2022-12-11 [1] CRAN (R 4.3.0)
#> DT 0.27 2023-01-17 [1] CRAN (R 4.3.0)
#> ellipsis 0.3.2 2021-04-29 [1] CRAN (R 4.3.0)
#> evaluate 0.20 2023-01-17 [1] CRAN (R 4.3.0)
#> fansi 1.0.4 2023-01-22 [1] CRAN (R 4.3.0)
#> fastmap 1.1.1 2023-02-24 [1] CRAN (R 4.3.0)
#> fs 1.6.2 2023-04-25 [1] CRAN (R 4.3.0)
#> glue 1.6.2 2022-02-24 [1] CRAN (R 4.3.0)
#> htmltools 0.5.5 2023-03-23 [1] CRAN (R 4.3.0)
#> htmlwidgets 1.6.2 2023-03-17 [1] CRAN (R 4.3.0)
#> jquerylib 0.1.4 2021-04-26 [1] CRAN (R 4.3.0)
#> jsonlite 1.8.4 2022-12-06 [1] CRAN (R 4.3.0)
#> knitr 1.42 2023-01-25 [1] CRAN (R 4.3.0)
#> lifecycle 1.0.3 2022-10-07 [1] CRAN (R 4.3.0)
#> magrittr 2.0.3 2022-03-30 [1] CRAN (R 4.3.0)
#> pillar 1.9.0 2023-03-22 [1] CRAN (R 4.3.0)
#> purrr 1.0.1 2023-01-10 [1] CRAN (R 4.3.0)
#> R.cache 0.16.0 2022-07-21 [1] CRAN (R 4.3.0)
#> R.methodsS3 1.8.2 2022-06-13 [1] CRAN (R 4.3.0)
#> R.oo 1.25.0 2022-06-12 [1] CRAN (R 4.3.0)
#> R.utils 2.12.2 2022-11-11 [1] CRAN (R 4.3.0)
#> R6 2.5.1 2021-08-19 [1] CRAN (R 4.3.0)
#> reprex 2.0.2 2022-08-17 [1] CRAN (R 4.3.0)
#> rlang 1.1.0 2023-03-14 [1] CRAN (R 4.3.0)
#> rmarkdown 2.21 2023-03-26 [1] CRAN (R 4.3.0)
#> rstudioapi 0.14 2022-08-22 [1] CRAN (R 4.3.0)
#> sass 0.4.5 2023-01-24 [1] CRAN (R 4.3.0)
#> sessioninfo 1.2.2 2021-12-06 [1] CRAN (R 4.3.0)
#> styler 1.9.1 2023-03-04 [1] CRAN (R 4.3.0)
#> tzdb 0.3.0 2022-03-28 [1] CRAN (R 4.3.0)
#> utf8 1.2.3 2023-01-31 [1] CRAN (R 4.3.0)
#> vctrs 0.6.2 2023-04-19 [1] CRAN (R 4.3.0)
#> withr 2.5.0 2022-03-03 [1] CRAN (R 4.3.0)
#> xfun 0.39 2023-04-20 [1] CRAN (R 4.3.0)
#> yaml 2.3.7 2023-01-23 [1] CRAN (R 4.3.0)
#>
#> [1] /Library/Frameworks/R.framework/Versions/4.3-arm64/Resources/library
#>
#> ──────────────────────────────────────────────────────────────────────────────
It looks like the problem is coming from htmlwidgets:::shouldEval()
, and I don't understand why that function recurses on lists. It eventually gets to the calendar column (which technically is implemented on a list, I would add an is.list()
method that returns FALSE
but it isn't generic) and tries to set its names to an integer vectors, which I don't allow in clock (names must be a character vector).
I feel like the core of the issue is that it is trying to recurse over the calendar object at all
This is probably a htmlwidgets bug more than a clock bug
Reported upstream
Unfortunately, the error here is a bit of a red herring. While I do have a PR to apply Davis' suggestions in htmlwidgets, once that obstacle is removed, data_table()
doesn't coerce the calendar objects to strings. Instead you'll have blank columns and potentially a client-side error when viewing the table.
I'm not sure if DT explicitly performs a format step, or if it does why it's not being applied to the clock_calendar
object.
For now, casting to character with as.character()
is probably the best thing to do. You might also want to open an issue in DT.