yihui / knitr

A general-purpose tool for dynamic report generation in R
https://yihui.org/knitr/
2.38k stars 873 forks source link

kable: sanitize column names (feature request) #1427

Open stla opened 7 years ago

stla commented 7 years ago

Hello,

Similarly to the options sanitize.colnames.function and sanitize.text.function of xtable::print.xtable, it would be nice to have options escape.colnames and escape.text in kable, to respectively escape the column names and the body of the table. Because we sometimes want to escape in the body but not in the header.

pa0 commented 6 years ago

I think something similar is in 'kableExtra' package.

cderv commented 6 years ago

Yes, you can format using kableExtra::cell_spec or kableExtra::text_spec. They have an escape argument and apply to Latex or HTML. Also, xtable use xtable::sanitize with default options. You can use this function as to prepare your data the print with kable(..., escape = FALSE). Personally, I find it interesting that formatting option lives in another package. kableExtra is pretty powerful. You should give it a try to see if it fits your need.

@stla Could you provide a reproductible exampe of what you do with xtable and to have a use case and something to test with ?

stla commented 6 years ago

Hmmm it was one year ago, I don't really remember. I think I had a table with some R² in the column names. The exponent 2 requires the math mode. But yes, I use kableExtra.

cderv commented 6 years ago

Ok. So if this feature is already in kableExtra, there is no need to work on including it in knitr, isn't it ?

stla commented 6 years ago

I didn't know kableExtra::cell_spec and kableExtra::text_spec and I don't understand their purpose (the help explains nothing). Does this allow to escape separately in the column names and in the cells ? Of course if it is possible there's no need to include that in knitr.

cderv commented 6 years ago

But yes, I use kableExtra.

Sorry, I misunderstood. I thought you had managed to get what you want with kableExtra.

About cell_spec and text_spec, docs shows that they can be used in combination with data manipulation package to prepare the table, including escaping.

If you can create a reprex of what you want (with xtable for example) and what you tried with kableExtra, it will be easier for me to test, and see if knitr can evolve to include this. Without, I can't do very much.

stla commented 6 years ago

I don't remember if I had managed actually... I will look into my archives and create a reprex if needed. I didn't know these docs of cell_spec and text_spec, they look great. I gonna study that. Thanks.

cderv commented 3 years ago

Here is a summary of the situations followed by a reproducible example :

---
title: test
output:
  pdf_document: 
    keep_tex: TRUE
---

This is the kind of table to print, using special char in colnames and some raw latex in rownames. 

```{r, results='asis'}
money <- matrix(c("$1,000","$900","$100"), ncol = 3,
dimnames = list("$\\alpha$",
c("Income (US$)","Expenses (US$)",
"Profit (US$)")))

xtable allow to not escape rownames for example

library(xtable)
print(xtable(money))
print(xtable(money), sanitize.rownames.function = identity)

But with knitr, only all or nothing. So, this will error as $ is not escaped is colnames

library(knitr)
options(knitr.table.format = "latex")
kable(money, escape = FALSE)

But we need escape = FALSE in kable for the rownname. We can do by preparing the data so it will work

money1 <- money
colnames(money1) <- xtable::sanitize(colnames(money1))
money1 <- apply(money1, 2, xtable::sanitize)

kable(money1, escape = FALSE)
money2 <- money
colnames(money2) <- knitr:::escape_latex(colnames(money2))
money2 <- apply(money2, 2, knitr:::escape_latex)
kable(money2, escape = FALSE)


Having a way to configure this could be interesting, even if the workaround is data manipulation when you need to output raw latex.