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

calendar columns break DT::datatable() #335

Closed
maxheld83 opened this issue Apr 25, 2023 · 4 comments
Closed

calendar columns break DT::datatable() #335

maxheld83 opened this issue Apr 25, 2023 · 4 comments

Comments

@maxheld83
Copy link
Member

maxheld83 commented Apr 25, 2023

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
#> 
#> ──────────────────────────────────────────────────────────────────────────────
@DavisVaughan
Copy link
Member

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

@DavisVaughan
Copy link
Member

This is probably a htmlwidgets bug more than a clock bug

@DavisVaughan
Copy link
Member

Reported upstream

@gadenbuie
Copy link

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.

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

3 participants