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

using kable_style with position on a table with a caption #221

Closed
soerensen3 opened this issue Jun 26, 2018 · 10 comments
Closed

using kable_style with position on a table with a caption #221

soerensen3 opened this issue Jun 26, 2018 · 10 comments
Labels

Comments

@soerensen3
Copy link

The attached code produces a latex error for me when knitting to pdf:
r markdown code example

kable_styling( kable( cars, booktabs=T, caption="cars"), position = "float_right" )

! Extra }, or forgotten \endgroup.
\endwraptable ...kip \egroup \box \z@ \fi \egroup
\WF@floatstyhook \def \wid...
l.237 \end{wraptable}

The error disappears if I remove the kable_style part or the caption.

I'm using the cran tinytex package (v.0.5).

platform x86_64-pc-linux-gnu
arch x86_64
os linux-gnu
system x86_64, linux-gnu
status
major 3
minor 5.0
year 2018
month 04
day 23
svn rev 74626
language R
version.string R version 3.5.0 (2018-04-23)
nickname Joy in Playing

@haozhu233
Copy link
Owner

Hmm, it looks like wrapfigure can only recognize caption below the table, which is kind of odd. I will fix this issue.

@haozhu233 haozhu233 added the bug label Jun 26, 2018
@alapo
Copy link

alapo commented Jun 26, 2018

I just wanted to add to this. The kable_styling is not the problem. It's specifically the position function in kable_styling. In my code I don't get an error if I have

kable(td, "latex", booktabs = T, caption = "ERP Condition Abbreviations") %>%
     kable_styling(font_size = 7)

But I do get an error if I add position as shown below

kable(td, "latex", booktabs = T, caption = "ERP Condition Abbreviations") %>%
     kable_styling(font_size = 7, position = "float_right")

@haozhu233
Copy link
Owner

haozhu233 commented Jun 26, 2018

Using the OP's original example as an example.

kable_styling( kable(cars[1:2, 1:2], "latex", booktabs=T, caption="cars"), position = "float_right" )

gives you

\begin{wraptable}{r}{0pt}

\caption{\label{tab:}cars}   % <---
\centering
\begin{tabular}[t]{rr}
\toprule
speed & dist\\
\midrule
4 & 2\\
4 & 10\\
\bottomrule
\end{tabular}
\end{wraptable}

which won't work. However, if you move \caption{\label{tab:}cars} below \end{tabular}, it will start to work.

\begin{wraptable}{r}{0pt}
\centering
\begin{tabular}[t]{rr}
\toprule
speed & dist\\
\midrule
4 & 2\\
4 & 10\\
\bottomrule
\end{tabular}
\caption{\label{tab:}cars}       % <---
\end{wraptable}

This is more like a behavior for wrapfigure, which provides that wraptable environment. I guess because it was originally designed for figures, the author made a decision to only accept caption at bottom? 😂The internal mechanism is totally a mystery for me.

What I can do here is to add an extra step to move that caption line to the bottom if that exists. I'm not very sure because 1. I'm not sure if this is the only solution 2. I prefer to keep caption on top... If any latex savvy people are reading this thread, please let me know if you have a good solution. Thanks

@soerensen3
Copy link
Author

Thank you for your quick responses, that would be great as I really need this for layouting my thesis! Unfortunately I am a bloody beginner on latex.

@haozhu233
Copy link
Owner

@soerensen3 well, if you just need a quick and easy solution, good news is that you can use kableExtra with xtable which does put table caption at bottom... You just have to let kableExtra think you are feeding it a kable....😛

library(kableExtra)
library(xtable)

xtable2kable <- function(x) {
  out <- capture.output(print(x, table.placement = NULL))[-(1:2)]
  out <- paste(out, collapse = "\n")
  structure(out, format = "latex", class = "knitr_kable")
}

xtable(cars[1:5,1:2], caption = "Test") %>%
  xtable2kable() %>%
  kable_styling(position = "float_right")

@soerensen3
Copy link
Author

Thank you! This works perfectly! So in case this doesn't get fixed in time I will use this!

@haozhu233
Copy link
Owner

Yeah, if it's getting too "risky" to move that caption by kableExtra, this might be the permanent solution. I will make some changes to that xtable2kable function and include it in the 1.0 version of kableExtra anyway.

@DOH-KGC0303
Copy link

Hello @haozhu233 - This work around worked well for me for placing the table and giving it a header but I am unable to use the pack_rows() function with it. For example I tried:

xtable(cars[1:5,1:2], caption = "Test") %>%
xtable2kable() %>%
pack_rows("Age Group", 1, 2, bold=TRUE) %>%
kable_styling(position = "float_right")

That seemed to have no effect on the table. Is there any update on this issue? Or is there a way to add this to the work around? I tried to find a way to group rows in xtable() and was unsuccessful.

Thank you!

@RishiKowalski
Copy link

Has there been any update to this issue, preferably without moving the caption below the table? I am getting the same errors as OP whenever I set the table position = "float_left" or "float_right."

@asgersvenning
Copy link

I also had this issue while knitting to pdf, and created this extremely hacky workaround. The goal was merely to be able to use pack_rows with position="float_left/right", I didn't resolve the issue of moving the caption to the top unfortunately. Here is the code:

library(stringr)
fix_wrap_kable <- function(kbl) {

  kbl <- kbl %>% 
    str_remove(paste0("\\\\caption[{].+[}]\\n")) %>% # Removes the first caption
    str_replace("\\\\end[{]tabular[}]",
                paste0("\\\\end{tabular}\n\\\\caption{",attributes(kbl)$kable_meta$caption %>% # Adds the new caption using the string supplied in the kable 'caption' argument.
                # The '{0,100}' is just a hack around lookbehind needing a set length, so the function will not work if the table label is longer 
                         str_replace("(?<=[(]\\\\#.{0,100})[)]","}") %>% # Fixes and issue with pandoc syntax being mixed with LaTeX 
                         str_replace("\\label[{]|[(]\\\\#","\\\\\\\\label{"),"}\n")) %>% # Adds an appropriate amount of backslashes before "\label"
    set_attributes(attributes(kbl)) # Ensures that the returned object is still a kable
  
  attributes(kbl)$kable_meta$caption <- NA # Removes the caption from the metadata
  
  return(kbl)
}

basically it just removes the caption before the table and inserts it again afterwards. It should also work with bookdown::pdf_document2. For convenience the function is made to be used with the pipe system in accordance with the other functions in kableExtra/knitr.

Usage:

library(kableExtra)
kable(dat, caption = "PLACEHOLDER") %>%
  kable_styling(..., position="float_left") %>%
  pack_rows(...) %>%
  ... %>%
  fix_wrap_kable

Hopefully it is of use to someone, and at least it shows that it is possible to have a caption, while wrapping text around the kable and using grouped rows.

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

6 participants