kableExtra icon indicating copy to clipboard operation
kableExtra copied to clipboard

column_spec give error: Error in UseMethod("nodeset_apply") : no applicable method for 'nodeset_apply' applied to an object of class "NULL"

Open yuliaUU opened this issue 4 years ago • 17 comments

I have a data table I want to display for HTML report

BelQ= structure(list(Source = "Kalender 2019", `Sourse of Questions` = "The survey instruments were part of a larger survey that included other motivational constructs. The development and validation of these surveys is reported in prior work [18–22,59]. ",     Results = "PCA analysis reveals that for both genders, sense of belonging and identity were not separate from the Expectancy Value Theory constructs. Instead, sense of belonging was closely tied to self-efficacy, which was therefore labeled as “self-efficacy or belonging” component or factor. ", Questions = "Sense of Belonging or Self-efficacy (not separated in a paper):<br>1. Sometimes I worry that I do not belong in this physics class<br>2. I feel like I can be myself in this class<br>3. I am able to help my classmates with physics in the laboratory or in recitation<br>4. I understand concepts I have studied in physics<br>5. If I wanted to, I could be good at physics research<br>6. ",     Reference = "Kalender, Z. Y., Marshman, E., Schunn, C. D., Nokes-Malach, T. J., & Singh, C. (2019). Gendered patterns in the construction of physics identity from motivational factors. Physical Review Physics Education Research, 15(2), [020119](https://journals.aps.org/prper/abstract/10.1103/PhysRevPhysEducRes.15.020119)"), row.names = c(NA, -1L), class = c("tbl_df", "tbl", "data.frame"))

when I try to produce a table I am not able to change teh widths of teh columns and I get teh error Error in UseMethod("nodeset_apply") : no applicable method for 'nodeset_apply' applied to an object of class "NULL"

BelQ  %>%  kbl() %>% 
   kable_styling(bootstrap_options = c("striped", "hover", "condensed"),font_size = 12, full_width = T) %>% 
   kableExtra::scroll_box(width = "100%", height = "500px") %>% 
     column_spec(1, width = "40em", include_thead=T) 

yuliaUU avatar Sep 25 '20 03:09 yuliaUU

I usually just use scroll_box at the very end. In your case, just flip the order of these two function will do the trick

... %>%
     column_spec(1, width = "40em", include_thead=T) %>%
     kableExtra::scroll_box(width = "100%", height = "500px")

haozhu233 avatar Oct 03 '20 12:10 haozhu233

I have installed the development version and I get the exact same error, no mater the order of the commands. I also get it with other commands when using include_thead=T.

sstoeckl avatar Oct 23 '20 21:10 sstoeckl

Oh, yeah, I think I probably broke it in a recent commit. I will look into it.

haozhu233 avatar Oct 23 '20 21:10 haozhu233

Hello haozhu, could you give us an update please? I installed recent version and the problem persists.

Thank you

Gateux avatar Jan 13 '21 12:01 Gateux

Hello - I wanted to check in on this as well. Do you expect a fix or have a suggestion as to how to fix this?

mhollander avatar Feb 11 '21 23:02 mhollander

BUMP Still no fix :'( Commenting for moral support.

PDiracDelta avatar Mar 02 '21 11:03 PDiracDelta

column_spec() seems to be broken. I can't change the font_size by column, for example. In my case , i find the error: column_spec give error: Error in UseMethod("nodeset_apply") : no applicable method for 'nodeset_apply' applied to an object of class "NULL" not when I knit the document, but when I loop-knit it , using parameters.

Fidelalencar avatar Mar 02 '21 22:03 Fidelalencar

Wanted to check if we can expect a fix or if there is a known workaround? I'm getting the same error when using include_thead = T

brink-tre avatar Mar 18 '21 18:03 brink-tre

Getting this error in pack_rows with label_row_css.

sahemo avatar Apr 08 '21 06:04 sahemo

I'm getting the same errors. I was able to convince it to knit, but it used 100+% of CPU for a few minutes and crashed RStudio. column_spec() works for me in other code blocks and documents, it seems that only in combination with scroll_box() does it become unstable.

aemacleod avatar Jun 15 '21 03:06 aemacleod

The commented line - https://github.com/haozhu233/kableExtra/commit/6fc251d1f66ae97adbda913bd7b6fe6e10751be8 is causing this I think

The problem seems to be that this offset is set to 1 for include_thead = TRUE which means the for loop reads beyond the end of the rows.

I'm not entirely sure what the existing code is trying to do - it's not obvious to me what is happening inside the include_thead branch - apologies for this - coming at it cold...

It looks like it should be easy to avoid the row overflow - e.g. just by changing the iteration sequence to something like for (io in seq(off + 1, length(all_contents_rows))) but I'm not actually sure if that leaves an underlying issue - is there something else going on with the rows here (should one be added?)

I'll go read the documentation....

slodge avatar Aug 18 '21 12:08 slodge

OK - think I can see what is happening now.

I'm afraid I haven't tested this in anger... but I have debugged through my local issue - think using i for body row columns and io for the format properties should work 👍 https://github.com/haozhu233/kableExtra/pull/646

slodge avatar Aug 18 '21 12:08 slodge

I've run into this issue as well, and can confirm that @slodge's PR https://github.com/haozhu233/kableExtra/pull/646 fixes the error.

LeeMendelowitz avatar Jan 19 '22 00:01 LeeMendelowitz

Bumping up that there is a PR here that seems to fix the issue but it hasn't been merged.

Bumping again!

jsbrook avatar Jul 13 '22 20:07 jsbrook

And again

tzerak avatar Aug 09 '22 13:08 tzerak

Same:

library(magrittr)
cars %>% 
  knitr::kable() %>%  
  kableExtra::column_spec(1, 
                          include_thead = TRUE, # works for FALSE
                          background = "red")
#> Error in UseMethod("nodeset_apply"): no applicable method for 'nodeset_apply' applied to an object of class "NULL"

Created on 2022-08-31 by the reprex package (v2.0.1)

Session info
sessioninfo::session_info()
#> ─ Session info ───────────────────────────────────────────────────────────────
#>  setting  value
#>  version  R version 4.1.2 (2021-11-01)
#>  os       macOS Big Sur 10.16
#>  system   x86_64, darwin17.0
#>  ui       X11
#>  language (EN)
#>  collate  en_AU.UTF-8
#>  ctype    en_AU.UTF-8
#>  tz       Australia/Melbourne
#>  date     2022-08-31
#>  pandoc   2.17.1.1 @ /Applications/RStudio.app/Contents/MacOS/quarto/bin/ (via rmarkdown)
#> 
#> ─ Packages ───────────────────────────────────────────────────────────────────
#>  package     * version date (UTC) lib source
#>  backports     1.4.1   2021-12-13 [1] CRAN (R 4.1.0)
#>  cli           3.3.0   2022-04-25 [1] CRAN (R 4.1.2)
#>  colorspace    2.0-3   2022-02-19 [1] R-Forge (R 4.1.2)
#>  digest        0.6.29  2021-12-01 [1] CRAN (R 4.1.0)
#>  evaluate      0.15    2022-02-18 [1] CRAN (R 4.1.2)
#>  fansi         1.0.3   2022-03-24 [1] CRAN (R 4.1.2)
#>  fastmap       1.1.0   2021-01-25 [1] CRAN (R 4.1.0)
#>  fs            1.5.2   2021-12-08 [1] CRAN (R 4.1.0)
#>  glue          1.6.2   2022-02-24 [1] CRAN (R 4.1.2)
#>  highr         0.9     2021-04-16 [1] CRAN (R 4.1.0)
#>  htmltools     0.5.3   2022-07-18 [1] CRAN (R 4.1.2)
#>  httr          1.4.3   2022-05-04 [1] CRAN (R 4.1.2)
#>  kableExtra    1.3.4   2021-02-20 [1] CRAN (R 4.1.2)
#>  knitr         1.39    2022-04-26 [1] CRAN (R 4.1.2)
#>  lifecycle     1.0.1   2021-09-24 [1] CRAN (R 4.1.0)
#>  magrittr    * 2.0.3   2022-03-30 [1] CRAN (R 4.1.2)
#>  munsell       0.5.0   2018-06-12 [1] CRAN (R 4.1.0)
#>  pillar        1.8.1   2022-08-19 [1] CRAN (R 4.1.2)
#>  pkgconfig     2.0.3   2019-09-22 [1] CRAN (R 4.1.0)
#>  purrr         0.3.4   2020-04-17 [1] CRAN (R 4.1.0)
#>  R.cache       0.15.0  2021-04-30 [1] CRAN (R 4.1.0)
#>  R.methodsS3   1.8.1   2020-08-26 [1] CRAN (R 4.1.0)
#>  R.oo          1.24.0  2020-08-26 [1] CRAN (R 4.1.0)
#>  R.utils       2.11.0  2021-09-26 [1] CRAN (R 4.1.0)
#>  R6            2.5.1   2021-08-19 [1] CRAN (R 4.1.0)
#>  reprex        2.0.1   2021-08-05 [1] CRAN (R 4.1.0)
#>  rlang         1.0.4   2022-07-12 [1] CRAN (R 4.1.2)
#>  rmarkdown     2.14    2022-04-25 [1] CRAN (R 4.1.2)
#>  rstudioapi    0.13    2020-11-12 [1] CRAN (R 4.1.0)
#>  rvest         1.0.2   2021-10-16 [1] CRAN (R 4.1.0)
#>  scales        1.2.1   2022-08-20 [1] CRAN (R 4.1.2)
#>  sessioninfo   1.2.2   2021-12-06 [1] CRAN (R 4.1.0)
#>  stringi       1.7.8   2022-07-11 [1] CRAN (R 4.1.2)
#>  stringr       1.4.1   2022-08-20 [1] CRAN (R 4.1.2)
#>  styler        1.6.2   2021-09-23 [1] CRAN (R 4.1.0)
#>  svglite       2.0.0   2021-02-20 [1] CRAN (R 4.1.0)
#>  systemfonts   1.0.3   2021-10-13 [1] CRAN (R 4.1.2)
#>  tibble        3.1.8   2022-07-22 [1] CRAN (R 4.1.2)
#>  utf8          1.2.2   2021-07-24 [1] CRAN (R 4.1.0)
#>  vctrs         0.4.1   2022-04-13 [1] CRAN (R 4.1.2)
#>  viridisLite   0.4.1   2022-08-22 [1] CRAN (R 4.1.2)
#>  webshot       0.5.3   2022-04-14 [1] CRAN (R 4.1.2)
#>  withr         2.5.0   2022-03-03 [1] CRAN (R 4.1.2)
#>  xfun          0.31    2022-05-10 [1] CRAN (R 4.1.2)
#>  xml2          1.3.3   2021-11-30 [1] CRAN (R 4.1.0)
#>  yaml          2.3.5   2022-02-21 [1] CRAN (R 4.1.2)
#> 
#>  [1] /Library/Frameworks/R.framework/Versions/4.1/Resources/library
#> 
#> ──────────────────────────────────────────────────────────────────────────────

emitanaka avatar Aug 31 '22 04:08 emitanaka

I just hit this same error again... over a year after the PR with a fix...

Is this project still alive? Do you need anyone else to assist?

slodge avatar Nov 18 '22 17:11 slodge

did you tried their new function kbl() instead of kable() (https://cran.r-project.org/web/packages/kableExtra/vignettes/awesome_table_in_html.html)? may be it is resolved there?

yuliaUU avatar Nov 18 '22 17:11 yuliaUU

@yuliaUU like this?

> cars %>% 
+   kableExtra::kbl() %>%  
+   kableExtra::column_spec(1, 
+                           include_thead = TRUE, # works for FALSE
+                           background = "red")
Error in UseMethod("nodeset_apply") : 
  no applicable method for 'nodeset_apply' applied to an object of class "NULL"

I was the one who submitted the #646 PR - it's a one character fix, but took some digging to find... it's a shame that it continues to cause pain :/

slodge avatar Nov 21 '22 08:11 slodge

If anyone wants a single code file to source in their app/report/script then this works as long as you call it after library(kableExtra)

# THIS FILE BASED FROM https://raw.githubusercontent.com/slodge/kableExtra/master/R/column_spec.R
# See https://github.com/haozhu233/kableExtra/pull/646 (open >1 year currently)

#' Specify the look of the selected column
#'
#' @description This function allows users to select a column and then specify
#' its look.
#'
#' @param kable_input Output of `knitr::kable()` with `format` specified
#' @param column A numeric value or vector indicating which column(s) to be selected.
#' @param width A character string telling HTML & LaTeX how wide the column
#' needs to be, e.g. "10cm", "3in" or "30em".
#' @param bold T/F value or vector to control whether the text of the selected
#' column need to be bolded.
#' @param italic T/F value or vector to control whether the text of the
#' selected column need to be emphasized.
#' @param monospace T/F value or vector to control whether the text of the
#' selected column need to be monospaced (verbatim)
#' @param underline T/F value or vector to control whether the text of the
#' selected row need to be underlined
#' @param strikeout T/F value or vector to control whether the text of the
#' selected row need to be striked out.
#' @param color A character string or vector for column text color. Here please
#' pay attention to the differences in color codes between HTML and LaTeX.
#' @param background A character string or vector for column background color. Here please
#' pay attention to the differences in color codes between HTML and LaTeX.
#' @param border_left A logical variable indicating whether there should be a
#' border line on the left of the selected column. In HTML, you can also pass
#' in a character string for the CSS of the border line
#' @param border_right A logical variable indicating whether there should be a
#' border line on the right of the selected column. In HTML, you can also pass
#' in a character string for the CSS of the border line
#' @param width_min Only for HTML table. Normal column width will automatically
#' collapse when the window cannot hold enough contents. With this `width_min`,
#' you can set up a column with a width that won't collapse even when the
#' window is not wide enough.
#' @param width_max Only for HTML table. `width_max` defines the maximum width
#' of table columns.
#' @param extra_css A vector of extra css text to be passed into the cells of
#' the column.
#' @param include_thead T/F. A HTML only feature to contoll whether the
#' header row will be manipulated. Default is `FALSE`.
#' @param latex_column_spec Only for LaTeX tables.  Code to replace the column
#' specification.  If not `NULL`, will override all other arguments.
#' @param latex_valign vertical alignment. Only works when you specified column
#'  width. Choose among `p`, `m`, `b`.
#' @param link A vector of strings for url links.
#' @param new_tab T/F for whether to open up the new link in new tab
#' @param tooltip A vector of strings to be displayed as tooltip.
#' Obviously, this feature is only available in HTML. Read the package
#' vignette to see how to use bootstrap tooltip css to improve the loading
#' speed and look.
#' @param popover Similar with tooltip but can hold more contents. The best way
#' to build a popover is through `spec_popover()`. If you only provide a text
#' string, it will be used as content. Note that You have to enable this
#' bootstrap module manually. Read the package vignette to see how.
#' @param image Vector of image paths.
#'
#' @details Use `latex_column_spec` in a LaTeX table to change or
#' customize the column specification.  Because of the way it is handled
#' internally, any backslashes must be escaped.
#'
#' @examples
#' \dontrun{
#' x <- knitr::kable(head(mtcars), "html")
#' column_spec(x, 1:2, width = "20em", bold = TRUE, italic = TRUE)
#' x <- knitr::kable(head(mtcars), "latex", booktabs = TRUE)
#' column_spec(x, 1, latex_column_spec = ">{\\\\color{red}}c")
#' }
#' @export
column_spec <- function(kable_input, column,
                        width = NULL, bold = FALSE, italic = FALSE,
                        monospace = FALSE, underline = FALSE, strikeout = FALSE,
                        color = NULL, background = NULL,
                        border_left = FALSE, border_right = FALSE,
                        width_min = NULL, width_max = NULL,
                        extra_css = NULL, include_thead = FALSE,
                        latex_column_spec = NULL, latex_valign = 'p',
                        link = NULL, new_tab = TRUE,
                        tooltip = NULL, popover = NULL, image = NULL) {
  if (!is.numeric(column)) {
    stop("column must be numeric. ")
  }
  kable_format <- attr(kable_input, "format")
  if (!kable_format %in% c("html", "latex")) {
    warning("Please specify format in kable. kableExtra can customize either ",
            "HTML or LaTeX outputs. See https://haozhu233.github.io/kableExtra/ ",
            "for details.")
    return(kable_input)
  }
  if (kable_format == "html") {
    return(kabelcolumn_spec_html_hacked(kable_input, column, width,
                            bold, italic, monospace,
                            underline, strikeout,
                            color, background,
                            border_left, border_right,
                            width_min, width_max,
                            extra_css, include_thead,
                            link, new_tab, tooltip, popover, image))
  }
  if (kable_format == "latex") {
    return(kableExtra:::column_spec_latex(kable_input, column, width,
                             bold, italic, monospace,
                             underline, strikeout,
                             color, background,
                             border_left, border_right,
                             latex_column_spec, latex_valign, include_thead,
                             link, image))
  }
}

kabelcolumn_spec_html_hacked <- function(kable_input, column, width,
                             bold, italic, monospace,
                             underline, strikeout,
                             color, background,
                             border_left, border_right,
                             width_min, width_max,
                             extra_css, include_thead,
                             link, new_tab, tooltip, popover, image) {
  
  kable_attrs <- attributes(kable_input)
  kable_xml <- kableExtra:::kable_as_xml(kable_input)
  kable_tbody <- kableExtra:::xml_tpart(kable_xml, "tbody")
  
  group_header_rows <- attr(kable_input, "group_header_rows")
  all_contents_rows <- seq(1, length(xml2::xml_children(kable_tbody)))
  
  if (!is.null(group_header_rows)) {
    all_contents_rows <- all_contents_rows[!all_contents_rows %in%
                                             group_header_rows]
  }
  
  # Border css
  border_l_css <- "1px solid"
  border_r_css <- "1px solid"
  if (is.character(border_left)) {
    border_l_css <- border_left
    border_left <- T
  }
  if (is.character(border_right)) {
    border_r_css <- border_right
    border_right <- T
  }
  
  if (include_thead) {
    nrows <- length(all_contents_rows) + 1
    off <- 1
    
    bold <- kableExtra:::ensure_len_html(bold, nrows, "bold")
    italic <- kableExtra:::ensure_len_html(italic, nrows, "italic")
    monospace <- kableExtra:::ensure_len_html(monospace, nrows, "monospace")
    underline <- kableExtra:::ensure_len_html(underline, nrows, "underline")
    strikeout <- kableExtra:::ensure_len_html(strikeout, nrows, "strikeout")
    color <- kableExtra:::ensure_len_html(color, nrows, "color")
    background <- kableExtra:::ensure_len_html(background, nrows,"background")
    link <- kableExtra:::ensure_len_html(link, nrows, "link")
    new_tab <- kableExtra:::ensure_len_html(new_tab, nrows, "new_tab")
    tooltip <- kableExtra:::ensure_len_html(tooltip, nrows, "tooltip")
    popover <- kableExtra:::ensure_len_html(popover, nrows, "popover")
    image <- kableExtra:::ensure_len_html(image, nrows, "image")
    
    kable_thead <- kableExtra:::xml_tpart(kable_xml, "thead")
    nrow_thead <- length(xml2::xml_children(kable_thead))
    for (j in column) {
      target_cell <- xml2::xml_child(xml2::xml_child(kable_thead, nrow_thead), j)
      kableExtra:::column_spec_html_cell(
        target_cell, width, width_min, width_max,
        bold[1], italic[1], monospace[1], underline[1], strikeout[1],
        color[1], background[1], border_left, border_right,
        border_l_css, border_r_css,
        extra_css,
        link[1], new_tab[1], tooltip[1], popover[1], image[1]
      )
    }
  } else {
    nrows <- length(all_contents_rows)
    off <- 0
    
    bold <- kableExtra:::ensure_len_html(bold, nrows, "bold")
    italic <- kableExtra:::ensure_len_html(italic, nrows, "italic")
    monospace <- kableExtra:::ensure_len_html(monospace, nrows, "monospace")
    underline <- kableExtra:::ensure_len_html(underline, nrows, "underline")
    strikeout <- kableExtra:::ensure_len_html(strikeout, nrows, "strikeout")
    color <- kableExtra:::ensure_len_html(color, nrows, "color")
    background <- kableExtra:::ensure_len_html(background, nrows,"background")
    link <- kableExtra:::ensure_len_html(link, nrows, "link")
    new_tab <- kableExtra:::ensure_len_html(new_tab, nrows, "new_tab")
    tooltip <- kableExtra:::ensure_len_html(tooltip, nrows, "tooltip")
    popover <- kableExtra:::ensure_len_html(popover, nrows, "popover")
    image <- kableExtra:::ensure_len_html(image, nrows, "image")
  }
  
  for (i in seq(length(all_contents_rows))) {
    for (j in column) {
      io <- i + off
      target_cell <- xml2::xml_child(xml2::xml_child(kable_tbody, all_contents_rows[i]), j)
      kableExtra:::column_spec_html_cell(
        target_cell, width, width_min, width_max,
        bold[io], italic[io], monospace[io], underline[io], strikeout[io],
        color[io], background[io], border_left, border_right,
        border_l_css, border_r_css,
        extra_css,
        link[io], new_tab[io], tooltip[io], popover[io], image[io]
      )
    }
  }
  
  out <- kableExtra:::as_kable_xml(kable_xml)
  attributes(out) <- kable_attrs
  if (!"kableExtra" %in% class(out)) class(out) <- c("kableExtra", class(out))
  return(out)
}

slodge avatar Nov 21 '22 15:11 slodge

Is this package dead? Captain going down with the ship?

half-normal avatar Mar 01 '23 06:03 half-normal