sweave, xtable, longtable and alternating row colors…problems with `add.to.row`

旧巷老猫 提交于 2019-12-07 18:04:47

问题


This existing question covers a way to alternate row colors in a latex table by post-processing the output from print.xtable(), but I think it's possible to achieve the same thing by using the add.to.row argument of print.xtable() as described on stats.stackexchange, avoiding the need for post-processing, which is nice with Sweave. That answer deals with coloring the background of one specific row, but I think it can be extended to coloring all the odd rows.

The problem I'm running into has to do with the add.to.row argument, making the length of list pos equal the length of character vector command. The help file for print.xtable() describes:

add.to.row: a list of two components. The first component (which should be called 'pos') is a list contains the position of rows on which extra commands should be added at the end, The second component (which should be called 'command') is a character vector of the same length of the first component which contains the command that should be added at the end of the specified rows. Default value is 'NULL', i.e. do not add commands.

when using the longtable environment, you can use this add.to.row argument to define the "header" rows of your table that should be printed on every page, like so:

library(xtable)
my.df=data.frame(a=c(1:10),b=letters[1:10])
print(xtable(my.data.frame,caption="My Table"),
      tabular.environment="longtable",
      floating=FALSE,
      hline.after=c(-1,nrow(my.data.frame)),
      add.to.row=list(pos=list(0),command="\\hline \\endhead ")

I need to keep this functionality, and add the additional functionality that every other row should get the command \\rowcolor[gray]{0.8}

Sounds simple enough. pos should be something like list=(0,1,3,5,7,9) and command should be something like c("\\hline \\endhead ","\\rowcolor[gray]{0.8}","\\rowcolor[gray]{0.8}","\\rowcolor[gray]{0.8}","\\rowcolor[gray]{0.8}","\\rowcolor[gray]{0.8}")

Of course, I want to take advantage of some built in functions to build the odd-row sequence and the repetition of "\\rowcolor[gray]{0.8}", so I thought of:

pos=list(0,seq(from=1,to=nrow(my.df),by=2))

and

command=c("\\hline \\endhead ",
          rep("\\rowcolor[gray]{0.8}",length(seq(from=1,to=nrow(my.df),by=2))))

my problem is that the pos list above evaluates to:

> pos
[[1]]
[1] 0

[[2]]
[1] 1 3 5 7 9

which has length 2...it needs to have length 6 in this case.


回答1:


The trick is to flatten out the list. There may be a prettier way, the following does the trick.

pos=list(as.list(c(0,seq(from=1,to=nrow(my.df),by=2))))[[1]]

The whole package is then:

library(xtable)
my.df=data.frame(a=c(1:10),b=letters[1:10])

print(xtable(my.df,caption="My Table"),
      tabular.environment="longtable",
      floating=FALSE,
      hline.after=c(-1,nrow(my.df)),
      add.to.row=list(
      pos=list(as.list(c(0,seq(from=1,to=nrow(my.df),by=2))))[[1]],
      command=c("\\hline \\endhead ",
      rep("\\rowcolor[gray]{0.8}",length(seq(from=1,to=nrow(my.df),by=2)))))
      )

which produces

% latex table generated in R 2.14.2 by xtable 1.7-0 package
% Thu Jan 31 12:52:55 2013
\begin{longtable}{rrl}
  \hline
 & a & b \\ 
  \hline \endhead 1 &   1 & a \\ 
   \rowcolor[gray]{0.8}2 &   2 & b \\ 
  3 &   3 & c \\ 
   \rowcolor[gray]{0.8}4 &   4 & d \\ 
  5 &   5 & e \\ 
   \rowcolor[gray]{0.8}6 &   6 & f \\ 
  7 &   7 & g \\ 
   \rowcolor[gray]{0.8}8 &   8 & h \\ 
  9 &   9 & i \\ 
   \rowcolor[gray]{0.8}10 &  10 & j \\ 
   \hline
\hline
\caption{My Table}
\end{longtable}

the formatting of the latex is a little ugly, and since \rowcolor is supposed to come before the row, even though we specified 1,3,5,9 we get coloring on 2,4,6,8 of the output.



来源:https://stackoverflow.com/questions/14632307/sweave-xtable-longtable-and-alternating-row-colors-problems-with-add-to-row

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!