kableExtra icon indicating copy to clipboard operation
kableExtra copied to clipboard

`pack_rows` breaks sparklines

Open EinMaulwurf opened this issue 5 months ago • 2 comments

Describe the bug Using sparklines from the ltxsparklines package does not work with pack_rows. But I found a workaround.

To Reproduce

library(tidyverse)
library(kableExtra)
library(ltxsparklines)

data <- tibble(
  "name" = c("A", "B", "C", "D"),
  "values" = c(list(rnorm(10)), list(rnorm(10)), list(rnorm(10)), list(rnorm(10)))
) %>%
  mutate(
    mean = map_dbl(values, mean),
    sparkline = map_chr(values, ~ { sparkline(x = NULL, y = .x, width = 5) }),
  ) %>%
  select(-values)

# --------------------------------------------------------------
# Works fine
kbl(
  data,
  booktabs = TRUE,
  format = "latex",
  escape = FALSE
)

# Does not work
# Inserts multicolumn-stuff only after first row and breaks the sparkline-cell
kbl(
  data,
  booktabs = TRUE,
  format = "latex",
  escape = FALSE
) %>%
  pack_rows("Lorem", 1, 2) %>%
  pack_rows("Ipsum", 3, 4)


# Works fine again
kbl(
  data %>% select(-sparkline),
  booktabs = TRUE,
  format = "latex",
  escape = FALSE
) %>%
  pack_rows("Lorem", 1, 2) %>%
  pack_rows("Ipsum", 3, 4)

# --------------------------------------------------------------
# Replacing the newline in the sparklines string seems to do the trick
data_replaced <- tibble(
  "name" = c("A", "B", "C", "D"),
  "values" = c(list(rnorm(10)), list(rnorm(10)), list(rnorm(10)), list(rnorm(10)))
) %>%
  mutate(
    mean = map_dbl(values, mean),
    sparkline = map_chr(values, ~ { sparkline(x = NULL, y = .x, width = 5) %>% str_replace_all("\n", "||NEWLINE||") }),
  ) %>%
  select(-values)

# This now works
kbl(
  data_replaced,
  booktabs = TRUE,
  format = "latex",
  escape = FALSE
) %>%
  pack_rows("Lorem", 1, 2) %>%
  pack_rows("Ipsum", 3, 4)

EinMaulwurf avatar Jul 31 '25 14:07 EinMaulwurf

Thanks for the report. I see the same issue in the devel version.

This looks like it will be hard to fix in kableExtra, because it would be required to parse the multi-line latex source and recognize that the sparkline environment should fit all in one cell. (The parseLatex branch I was working on that did parse the latex has no problems with the newlines, but it's noticeably slower than the standard kableExtra.)

Could this be fixed in the ltxsparklines project instead? If it didn't insert newlines, you wouldn't need to delete them.

dmurdoch avatar Jul 31 '25 14:07 dmurdoch

@EinMaulwurf : One thing I don't understand about your workaround. You replaced newlines with "||NEWLINE||", and it works fine. Is this choice special? When I replace them with a single space it also works.

BTW, in case anyone else is reading this, you can do the replacement automatically by defining this function to hide the standard ltxsparklines::sparkline():

sparkline <- function (...) {
  result <- ltxsparklines::sparkline(...)
  gsub("\n", " ", result)
}

dmurdoch avatar Sep 01 '25 14:09 dmurdoch