Search code examples
rsweave

Why is sweave markup (<<>>=) not working in tabular environment?


I struggle with R and sweave in the tabular environment. I want to have cell markup depending on the content. Thus, I tried an if-condition within the tabular environment, but it does not work out. The

<<results=tex,echo=false, eval=true>>=
   if(1==1) cat("\\cellcolor{markRed}")
@

will not be evaluated and I have no idea why that is the case.

Could you please guide me to fix my problem?

Note: I don't want to facilitate xtable because I want a clear separation of calculation an presentation (r-scripts for calculations and a rather "stupid" rnw-file for presentation).

Thank you and best regards, karl

Minimal working example:

\documentclass{article} 
\usepackage{times} 

\usepackage{multirow,colortbl,xcolor}
\usepackage{booktabs} % for midrule in tables
\usepackage{threeparttable}  % for footnotes in tables

\definecolor{markRed}{rgb}{1.0, 0.01, 0.24}

\begin{document} 
\SweaveOpts{concordance=TRUE}

<<echo=false>>=
 df1=data.frame(Indicator=c("A1", "B2", "C3"))
 df1[, "x1"] <- c("1", "2", "3")
 df1[, "x2"] <- c("1", "2", "3")
 df1[, "x3"] <- c("1", "2", "3")
 
@ 
\section{Working example}
\begin{threeparttable}
\begin{tabular}{llcrrr}
\textbf{Class} & \textbf{Id} & \textbf{w} & \textbf{x1} & \textbf{x2}\tnote{1} & \textbf{x3} \\
\toprule
foo &
  foo & 
      $\frac{1}{6}$ &
      \Sexpr{df1[df1$Indicator=="A1", "x1"]}\% &
      \Sexpr{df1[df1$Indicator=="A1", "x2"]}\% &
      \Sexpr{df1[df1$Indicator=="A1", "x3"]}\\
<<results=tex,echo=false, eval=true>>=
 cat("bar & bar & $\\frac{1}{6}$ & 4 & ")
 if(1==1) cat("\\cellcolor{markRed}")
 cat("4 & 4 \\\\")
@ 
\end{tabular}%
\begin{tablenotes}
 \item[1] a note.
\end{tablenotes}
\end{threeparttable}

\section{Not Working example}
\begin{threeparttable}
\begin{tabular}{llcrrr}
\textbf{Class} & \textbf{Id} & \textbf{w} & \textbf{x1} & \textbf{x2}\tnote{1} & \textbf{x3} \\
\toprule
foo &
  foo & 
      $\frac{1}{6}$ &
      \Sexpr{df1[df1$Indicator=="A1", "x1"]}\% &
      \Sexpr{df1[df1$Indicator=="A1", "x2"]}\% &
      <<results=tex,echo=false, eval=true>>=
        if(1==1) cat("\\cellcolor{markRed}")
      @
      \Sexpr{df1[df1$Indicator=="A1", "x3"]}\\
<<results=tex,echo=false, eval=true>>=
 cat("bar & bar & $\\frac{1}{6}$ & 4 & ")
 if(1==1) cat("\\cellcolor{markRed}")
 cat("4 & 4 \\\\")
@ 
\end{tabular}%

\begin{tablenotes}
 \item[1] a note.
\end{tablenotes}
\end{threeparttable}

\end{document} 

Solution

  • When using Sweave(), the chunk markers need to be in column 1. So you need to change this

          $\frac{1}{6}$ &
          \Sexpr{df1[df1$Indicator=="A1", "x1"]}\% &
          \Sexpr{df1[df1$Indicator=="A1", "x2"]}\% &
          <<results=tex,echo=false, eval=true>>=
            if(1==1) cat("\\cellcolor{markRed}")
          @
          \Sexpr{df1[df1$Indicator=="A1", "x3"]}\\
    

    to this:

          $\frac{1}{6}$ &
          \Sexpr{df1[df1$Indicator=="A1", "x1"]}\% &
          \Sexpr{df1[df1$Indicator=="A1", "x2"]}\% &
    <<results=tex,echo=false, eval=true>>=
            if(1==1) cat("\\cellcolor{markRed}")
    @
          \Sexpr{df1[df1$Indicator=="A1", "x3"]}\\
    

    For what it's worth, if you use knitr::knit instead of Sweave(), the indentation of the chunk markers doesn't matter. You'll need to make other changes, though, for example

    <<results=tex,echo=false, eval=true>>=
    

    would become

    <<results="asis",echo=FALSE, eval=TRUE>>=
    

    because chunk options are evaluated as if they are R expressions. Generally speaking I'd advise making the switch: knitr is better in many ways.