printable table with partial bolding/italics within a cell - r

I'm looking for a way to print out a table from R, but with formatting within a cell, like having some of the text within a cell be bold or italic. Normally I would first make the appropriate data.frame/tibble and then I'd format and print it using a package like huxtable or kable. Looking over documentation for huxtable or kableExtra, it seems as though both packages treat formatting as properties of cells, implying that within-cell formatting is either unsupported or must be implemented some other way.
If I was making a ggplot, I'd use expression for text formatting, e.g.
library(tidyverse)
ggplot(data=mtcars) +
ggtitle(expression(paste(bold("bold part"), " not bold part")))
I thought I could be clever by putting expressions into a data.frame, but this doesn't seem to be supported:
data.frame(var = c(expression(paste(bold("bold part"), "not bold part")),
expression(paste(bold("bold part"), "not bold part"))
))
#> Error in as.data.frame.default(x[[i]], optional = TRUE): cannot coerce class ""expression"" to a data.frame

If you want to make changes to data tables, I recommend you use the grid and gridExtra packages to construct your table and then make changes to the theme parameters.
Without any data to play with I can't see exactly what you want but here's a general idea of what you could do (see below). I've included other aesthetic parameters, for future reference.
You could then generate a pdf output to your C drive, which could then be printed.
d <- data.frame(A = c(1,2,3,4,5),
B = c(6,7,8,9,10),
C = c(11,12,13,14,15))
pdf("Test.pdf", height = 11, width = 10)
grid.table(d, rows = NULL, theme = ttheme_minimal(
core=list(fg_params=list(
hjust=0,
x=0.1,
fontface=matrix(c(1,2,3))))))
dev.off()

Re huxtable, you're correct, but you can get round it. Here's a 1 row, 1 column example, assuming you are printing to HTML:
my_hux <- huxtable("<b>Bold part</b> Not bold part")
escape_contents(my_hux)[1, 1] <- FALSE
You can include arbitrary HTML. Something similar would work for TeX, obviously with TeX formatting instead.

Related

How to color one cell in my formattable in R

I'm trying to create a table in R with formattable. I can have already used formattable to create a table where the color depended on the values. But there is one cell that I just want to be red, no matter what is in the cell, and I can't figure out how to do this.
result_table <- cbind(Normal = c(1,2,3), Fraud = c(4,5,6))
row.names(result_table) <- c('Normal', "Suspicious", "Fraud")
my_df <- as.data.frame(result_table)
formattable(my_df)
I want to color normal vs normal green, fraud vs fraud green, normal vs fraud red, fraud vs normal red. But since I'm using formattable also for the other tables in my report, I'd like to use it here as well (so that all tables in my report have the same style.)
OK, so here is a solution, although not a perfect one. First, we define the formatters – functions that take the data and turn it into HTML code:
red.f <- formatter("span", style=x~style(color="red"))
green.f <- formatter("span", style=x~style(color="green"))
It is possible to make these functions conditional, but unfortunately neither is formatter well documented nor the authors foresaw your problem.
Now then.
my_df2 <- sapply(colnames(my_df), function(cn) {
sprintf(
ifelse(cn == rownames(my_df), green.f("%s"), red.f("%s")),
my_df[,cn]
)
})
my_df2 <- data.frame(my_df2)
rownames(my_df2) <- rownames(my_df)
formattable(my_df2)
Explanation: I cannot find a way to put the ifelse inside of the formatter. Therefore, I create a character vector with %s as a placeholder and fill it out with values from the column using sprintf. Then, I combine the vectors to a matrix using sapply, turn it into a data frame, add row names and presto.

Creating different indent for row names in pander

for the purpose of exporting a results table into word using R markdown, I found that pander has fulfilled almost all my needs. However, after a lot of searching I couldn't find a way to indent some of the row names in my table (the equivalent to add_indent in kable). For example, the first row's name is: "Level 1", and than I want the second row's name ("intercept") to be indented right. Is this possible? (I found pandoc.indent but didn't succeed in applying it on my table).
Attached is the current code I use for the table.
library(pander)
set.alignment('center', row.names = 'left')
panderOptions('missing', '')
pander::pander(df,split.cell = c(50,15,15,15), split.table = Inf,
emphasize.rownames = FALSE)
Thanks!

R plotmath - how to display an apostrophe

I am trying to print an apostrophe for the column name below in a table using tableGrob
"Kendall's~tau"
The end result is that the whole label is italicized without the ~ and tau being interpreted:
How do I correctly specify this?
I don't think it's helpful, but this is the theme that I've specified to tableGrob:
table_theme <- ttheme_default(
core = list(fg_params=list(fontsize = 6)),
colhead = list(fg_params=list(fontsize = 6, parse=TRUE)),
rowhead = list(fg_params=list(fontsize = 6, parse=TRUE)),
padding = unit(c(2, 3), "mm"))
The column name is interpreted via plotmath in grDevices -- the standard way of specifying mathematical annotation in figures generated in R.
Again it has nothing to do with how to specify the expression itself, but here is the table constructor:
tableGrob(stats_df,
theme = table_theme,
rows = c("Kendall's~tau"))
Here's a reproducible example:
library(gridExtra)
library(grid)
data(iris)
table_theme <- ttheme_default(rowhead = list(fg_params=list(parse=TRUE)))
grid.table(head(iris),
rows = c(letters[c(1:4)], "plotmath~works~omega", "Kendall's~tau"),
theme = table_theme)
This works:
library(gridExtra)
library(grid)
data(iris)
table_theme <- ttheme_default(rowhead = list(fg_params=list(parse=TRUE)))
grid.table(head(iris),
rows = c(letters[c(1:4)], "plotmath~works~omega", "Kendall's"~tau),
theme = table_theme)
Try with a backslash in your expression like "Kendall\'s~tau". It should work then.
I tried to use apostrophe with expressions to plot in ggplot. In my database is invalid to use ' in expressions, but this worked
expression(paste(u,"'",(t),sep=""))
But this "paste" also cause bad behaviour of the subindex expression expression(U[0]). So to use both together, this one worked
paste(expression(paste("u","'",sep="")),"/U[0]",sep="")
If anyone knows a easier way, I'd be very glad.
If your apostrophe is embedded in a longer string, along with special symbols like ~, these solutions will not work. The only thing I've found to work is using regular expression substitution.
#This doesn't work
stringWithApostrophe="Matt's and Louise's diner~...and~also Ben's diner~X^2"
qplot(1:10,1:10)+annotate("text",x=2,y=4,label=stringWithApostrophe,parse=T)
Error: "Error in parse(text = text[[i]]) : :1:5: unexpected string constant"
The problem is the special characters like tilde and apostrophe happening in the same quoted segment. So you have to separate "Matt's" from "Louise's" and "~". Here's the code to do that.
stringWithApostrophe2<-stringr::str_replace_all(pattern = "([^~()*]*'[^~()*']*)",replacement = "\"\\1\"",string=stringWithApostrophe)
qplot(1:10,1:10)+annotate("text",x=2,y=8,hjust=0,label=stringWithApostrophe2,parse=T)
Plots successfully. The final expression that plotmath in R parses correctly is:
""Matt's and Louise's diner"~...and~"also Ben's diner"~X^2"

grid.table and tableGrob in gridExtra package

I am trying to format the table using gridExtra package. The gridExtra package I have is 2.0 and R version is 3.2.1
I was going through answers here on stackoverflow about the formatting and the suggested options seem to work only with older version of the package. For example,
grid.table(data, h.even.alpha = 1, h.odd.alpha = 0,
v.even.alpha = 1, v.odd.alpha = 1,
gpar.corefill, gpar.coretext)
All of these options are shown as "unused arguments" in the latest version.
Searching further, I found that in new gridExtra package, formatting is defined probably inside theme, example -
tt <- ttheme_default(core=list(fg_params=list(hjust=1, x=0.95)),
colhead=list(fg_params=list(col="brown"))
and then doing
grid.table(data, theme=tt).
What I could not found was how these options inside theme is defined and how all the formatting which was possible in older version can now be done.
In particular, I am looking to do -
Left justification of columns
commas for big.marks (10000 as 10,000)
different row colors for even and odd row numbers
column header color
not showing row names (something like row.names=FALSE)
This recent answer shows how to alter the parameters, and Baptiste gives a link to further examples. As you notice in your question, to alter the formatting you use the theme argument; you can see what parameters to alter by looking at the output of ttheme_default()
# New theme paramters
myt <- ttheme_default(
# Use hjust and x to left justify the text
# Alternate the row fill colours
core = list(fg_params=list(hjust = 1, x=1),
bg_params=list(fill=c("yellow", "pink"))),
# Change column header to white text and red background
colhead = list(fg_params=list(col="white"),
bg_params=list(fill="red"))
)
# Example data - create some large numbers
dat <- mtcars[1:5,1:5]
dat$mpg <- dat$mpg*1000
grid.newpage()
grid.draw(tableGrob(format(dat, big.mark=","), theme=myt, rows=NULL))
The big.mark argument of format is used to add the comma separator, and rownames are removed using the rows=NULL argument.

Strange behavior of Latex table generated by Latex() from Hmisc package and Knitr

I have some code that I am using to make a table in Knitr. I have typed in some numbers manually to make the code reproducible.
Expenditure <- as.matrix(data.frame(c("41","55","71","84"),c("41","55","71","84"),c("41","55","71","84"),c("41","55","71","84"),c("41","55","71","84"),c("41","55","71","84"),c("41","55","71","84"),c("41","55","71","84")))
rownames(Expenditure) <- c("30000","40000","50000","60000")
colnames(Expenditure) <- as.character(seq(0,0.35,0.05)*100)
latex(Expenditure,
n.cgroup=c(8), cgroup=c("Largest Historical Drawdown"),
file="",
ctable=TRUE, caption="Shortfall Risk Table", caption.loc=c('top'), label="tab:SfRisk")
This gives the following Latex code:
%latex.default(Expenditure, n.cgroup = c(8), cgroup = c("Largest Historical Drawdown"), file = "", ctable = TRUE, caption = "Shortfall Risk Table", caption.loc = c("top"), label = "tab:SfRisk")%
\ctable[caption={Shortfall Risk Table}label=tab:SfRisk,pos=!tbp,]{lllllllll}{}{\FL
\multicolumn{1}{l}{\bfseries Expenditure}&\multicolumn{8}{c}{\bfseries Largest Historical Drawdown}\NN
\cline{2-9}
\multicolumn{1}{l}{}&\multicolumn{1}{c}{0}&\multicolumn{1}{c}{5}&\multicolumn{1}{c}{10}&\multicolumn{1}{c}{15}&\multicolumn{1}{c}{20}&\multicolumn{1}{c}{25}&\multicolumn{1}{c}{30}&\multicolumn{1}{c}{35}\ML
30000&41&41&41&41&41&41&41&41\NN
40000&55&55&55&55&55&55&55&55\NN
50000&71&71&71&71&71&71&71&71\NN
60000&84&84&84&84&84&84&84&84\LL
}
This produces a Latex table, but the caption has had the word "label" added to the end, so it says "Shortfall Risk Tablelabel". The word "Tablelabel" does not appear anywhere in the .tex document. I have searched for a solution to this but I can't find anything. Any help much appreciated!
I can't post an image because I don't have a high-enough "reputation", apparently. So I have put one at johnbutters.org/examples
As per cbeleites's comment, it's a problem with the ctable code that comes out of the latex() function. The solution is to have "ctable=FALSE". This still gives the slightly odd output line: "\caption{Shortfall Risk Table\label{tab:SfRisk}}" but the final output looks OK.

Resources