[R] shading cells in a latex table by value

Duncan Murdoch murdoch.duncan at gmail.com
Wed Jul 23 17:31:43 CEST 2014


On 23/07/2014, 9:31 AM, Michael Friendly wrote:
> I want to create latex tables of values where the cell background is 
> shaded according to the
> table value.  For example:
> 
> set.seed(1) # reproducibility
> mat <- matrix(3 * rnorm(12), 3, 4)
> rownames(mat) <- letters[1:3]
> colnames(mat) <- LETTERS[1:4]
> 
>  > round(mat,1)
>       A    B   C    D
> a -1.9  4.8 1.5 -0.9
> b  0.6  1.0 2.2  4.5
> c -2.5 -2.5 1.7  1.2
> 
> # colors to use:  blue(+), red(-) with two shading levels,
> # depending on abs(x) > 2
> cols <- c(rgb(0.85,0.85,1),
>            rgb(0.7 ,0.7 ,1),
>            rgb(1,0.85,0.85),
>            rgb(1,0.7 ,0.7 ))
> cols <- matrix(cols, 2,2)
> 
> cellcol <- apply(mat, 1:2,
>                   function(x) {i<-1+(x>0); j<-1+(abs(x)>2); cols[i,j]})
>  >
>  > cellcol
>    A         B         C         D
> a "#D9D9FF" "#FFB2B2" "#B2B2FF" "#D9D9FF"
> b "#B2B2FF" "#B2B2FF" "#FFB2B2" "#FFB2B2"
> c "#FFD9D9" "#FFD9D9" "#B2B2FF" "#B2B2FF"
> 
> What I want is to generate a latex table of mat, with each cell colored 
> according to cellcol.
> I can do this manually as shown below, using the latex colortbl package 
> and a macro
> \cell{value}{color}.  How can I produce this in R?
> 
> # colortab-test.tex -----------------------
> %% Latex part:
> 
> \documentclass[11pt]{article}
> \usepackage{xcolor,colortbl}
> 
> # wrap each cell with command to define background color
> \newcommand{\cell}[2]{\multicolumn{1}%
>     {>{\columncolor{#1}}r}{#2}}
> 
> \definecolor{blueA}{rgb}{0.85,0.85,1}
> \definecolor{blueB}{rgb}{0.7 ,0.7 ,1}
> \definecolor{redA}{rgb}{1,0.85,0.85}
> \definecolor{redB}{rgb}{1,0.7 ,0.7 }
> 
> \begin{document}
> 
> \begin{tabular}{lcccc}
>      &  A  & B  & C  & D \\
>   a & \cell{-1.9}{redB} & \cell{4.8}{blueA} & \cell{1.5}{blueB} & 
> \cell{-0.9}{redB} \\
>   b & \cell{0.6}{blueB} & \cell{1.0}{blueB} & \cell{2.2}{blueA} &  
> \cell{4.5}{blueA} \\
>   c  \cell{-2.5}{redA}  & \cell{-2.5}{redB} & \cell{1.7}{blueB} &  
> \cell{1.2}{blueB}  \\
> \end{tabular}
> \end{document}
> # --------------------------------------------

You could do this using the tables package, with a custom format
function.  Normally you would calculate the table entries within the
formula, but you can also convert a matrix.

For example,

colornames <- matrix(c("blueA", "blueB", "redA", "redB"),
                   2,2)

myformat <- function(x) {
  i<-1+(x>0)
  j<-1+(abs(x)>2)
  paste0("\\cell{", round(x,1), "}{", colornames[cbind(i,j)], "}")
}

tab <- as.tabular(mat, like=tabular(Heading()*row ~
Heading()*col*Format(myformat()),
                        data=data.frame(row=rep(letters[1:3],4),
                                        col=rep(LETTERS[1:4],3))))
latex(tab)

produces

\begin{tabular}{lcccc}
\hline
  & A & B & C & \multicolumn{1}{c}{D} \\
\hline
a  & \cell{-1.9}{blueA} & \cell{4.8}{redB} & \cell{1.5}{blueB} &
\cell{-0.9}{blueA} \\
b  & \cell{0.6}{blueB} & \cell{1}{blueB} & \cell{2.2}{redB} &
\cell{4.5}{redB} \\
c  & \cell{-2.5}{redA} & \cell{-2.5}{redA} & \cell{1.7}{blueB} &
\cell{1.2}{blueB} \\
\hline
\end{tabular}

It's a little cumbersome to tack the formatting onto an existing matrix;
the normal expectation is that a tabular() call would be used to compute
the cell values as well.

Duncan Murdoch



More information about the R-help mailing list