12

The following table was created with the following LaTeX-code (mwe):

table

\documentclass{article} \usepackage{tabu} \usepackage{multirow} \begin{document} \newtabulinestyle{stip=on 1.5pt off 2pt} \begin{tabu} to \linewidth {X[0.8l]X[2.5l]X[c]X[c]X[c]X[c]X[c]} \hline \rowfont{\bfseries} \multicolumn{2}{c}{\multirow{2}{*} {NUMBERS}} & \multicolumn{2}{c}{Type} & \multicolumn{2}{c}{Size} & \multirow{2}{*}{All} \\ & & A & B & Big & Small & \\ \hline \multicolumn{2}{l}{Good} & 1 & 4 & 2 & 3 & 5\\ \tabucline[stip]{-} \multirow{3}{*}{Ugly} & Cow & 7 & 1 & 4 & 4 & 8 \\ \tabucline[stip]{2-} & Goat & 1 & 2 & 0 & 3 & 3 \\ \tabucline[stip]{2-} & Horse & 2& 1 & 3 & 0 & 3 \\ \tabucline[stip]{-} \multicolumn{2}{l}{Bad}& 12 & 1 & 6 & 7 & 13 \\ \hline \rowfont{\bfseries} \multicolumn{2}{l}{TOTAL} & 23 & 9 & 15 & 17 & 32 \\ \hline \end{tabu} \end{document} 

Is it possible to create a macro that makes such tables from the following input?

 \begin{mytable}[NUMBERS] 1 & 4 & 2 & 3 & 5 \\ 7 & 1 & 4 & 4 & 8 \\ 1 & 2 & 0 & 3 & 3 \\ 2 & 1 & 3 & 0 & 3 \\ 12 & 1 & 6 & 7 & 13 \\ 23 & 9 & 15 & 17 & 32 \end{mytable} 

I have been playing around with pgfplotstable for a while, but especially the multirows are giving me a headache.

(Ideally, even the sums would be automatically calculated and an error would be returned if the numbers did not match. (A + B = Big + Small). But this is luxury rather than necessary.)

2
  • Some information you should probably give: will your table always have the same headings? Will it always have the same dimensions? Commented Nov 17, 2012 at 17:41
  • @Scott H. The answer is yes in both cases: it is always the exact same table, except for the numbers in it and the content of the very first cell ("NUMBERS"). So in fact just "prepending" a given first column (in fact a double column including multirows and multicolumns) and a first row would be a major step in the good direction that I have not managed to take yet. Commented Nov 17, 2012 at 18:02

2 Answers 2

12

Updated answer shows two versions, a simple one without calculation and checks and a second one which does the calculation.

enter image description here

\documentclass{article} \usepackage{tabu} \usepackage{multirow} \begin{document} \newtabulinestyle{stip=on 1.5pt off 2pt} \begin{tabu} to \linewidth {X[0.8l]X[2.5l]X[c]X[c]X[c]X[c]X[c]} \hline \rowfont{\bfseries} \multicolumn{2}{c}{\multirow{2}{*} {NUMBERS}} & \multicolumn{2}{c}{Type} & \multicolumn{2}{c}{Size} & \multirow{2}{*}{All} \\ & & A & B & Big & Small & \\ \hline \multicolumn{2}{l}{Good} & 1 & 4 & 2 & 3 & 5\\ \tabucline[stip]{-} \multirow{3}{*}{Ugly} & Cow & 7 & 1 & 4 & 4 & 8 \\ \tabucline[stip]{2-} & Goat & 1 & 2 & 0 & 3 & 3 \\ \tabucline[stip]{2-} & Horse & 2& 1 & 3 & 0 & 3 \\ \tabucline[stip]{-} \multicolumn{2}{l}{Bad}& 12 & 1 & 6 & 7 & 13 \\ \hline \rowfont{\bfseries} \multicolumn{2}{l}{TOTAL} & 23 & 9 & 15 & 17 & 32 \\ \hline \end{tabu} \def\mytable[#1]#2\\#3\\#4\\#5\\#6\\#7\end#8{% \begin{tabu} to \linewidth {X[0.8l]X[2.5l]X[c]X[c]X[c]X[c]X[c]} \hline \rowfont{\bfseries} \multicolumn{2}{c}{\multirow{2}{*} {#1}} & \multicolumn{2}{c}{Type} & \multicolumn{2}{c}{Size} & \multirow{2}{*}{All} \\ & & A & B & Big & Small & \\ \hline \multicolumn{2}{l}{Good} &#2\\\tabucline[stip]{-} \multirow{3}{*}{Ugly} & Cow & #3 \\ \tabucline[stip]{2-} & Goat & #4\\ \tabucline[stip]{2-} & Horse & #5 \\ \tabucline[stip]{-} \multicolumn{2}{l}{Bad}& #6 \\ \hline \rowfont{\bfseries} \multicolumn{2}{l}{TOTAL} & #7 \\ \hline \end{tabu}% \end{mytable}} \begin{mytable}[NUMBERS] 1 & 4 & 2 & 3 & 5 \\ 7 & 1 & 4 & 4 & 8 \\ 1 & 2 & 0 & 3 & 3 \\ 2 & 1 & 3 & 0 & 3 \\ 12 & 1 & 6 & 7 & 13 \\ 23 & 9 & 15 & 17 & 32 \end{mytable} \def\testrowone#1&#2&#3&#4&#5\\{% \ifnum\numexpr#1+#2\relax=#5\else \typeout{A+B != All}\fi \ifnum\numexpr#3+#4\relax=#5\else \typeout{big+small != All}\fi } \def\cella#1&#2&#3&#4&#5\\{#1} \def\cellb#1&#2&#3&#4&#5\\{#2} \def\cellc#1&#2&#3&#4&#5\\{#3} \def\celld#1&#2&#3&#4&#5\\{#4} \def\celle#1&#2&#3&#4&#5\\{#5} \def\mytableb[#1]#2\\#3\\#4\\#5\\#6\\#7\end#8{% \testrowone#2\\ \begin{tabu} to \linewidth {X[0.8l]X[2.5l]X[c]X[c]X[c]X[c]X[c]} \hline \rowfont{\bfseries} \multicolumn{2}{c}{\multirow{2}{*} {#1}} & \multicolumn{2}{c}{Type} & \multicolumn{2}{c}{Size} & \multirow{2}{*}{All} \\ & & A & B & Big & Small & \\ \hline \multicolumn{2}{l}{Good} &#2\\\tabucline[stip]{-} \multirow{3}{*}{Ugly} & Cow & #3 \\ \tabucline[stip]{2-} & Goat & #4\\ \tabucline[stip]{2-} & Horse & #5 \\ \tabucline[stip]{-} \multicolumn{2}{l}{Bad}& #6 \\ \hline \rowfont{\bfseries} \multicolumn{2}{l}{TOTAL} & \the\numexpr \cella#2\\+\cella#3\\+\cella#4\\+\cella#5\\+\cella#6\\ \relax & \the\numexpr \cellb#2\\+\cellb#3\\+\cellb#4\\+\cellb#5\\+\cellb#6\\ \relax & \the\numexpr \cellc#2\\+\cellc#3\\+\cellc#4\\+\cellc#5\\+\cellc#6\\ \relax & \the\numexpr \celld#2\\+\celld#3\\+\celld#4\\+\celld#5\\+\celld#6\\ \relax & \the\numexpr \celle#2\\+\celle#3\\+\celle#4\\+\celle#5\\+\celle#6\\ \relax \end{tabu}% \end{mytableb}} \begin{mytableb}[NUMBERS] 1 & 4 & 2 & 3 & 5 \\ 7 & 1 & 4 & 4 & 8 \\ 1 & 2 & 0 & 3 & 3 \\ 2 & 1 & 3 & 0 & 3 \\ 12 & 1 & 6 & 7 & 13 \\ \end{mytableb} \end{document} 
6
  • Wow. Your answer is a nice example of what 'simple/plain' TeX can do, thank you! Commented Nov 17, 2012 at 19:19
  • 2
    @DavidCarlisle -- oh, please don't mash the contents of each line up against the rule above it! you know better! Commented Nov 17, 2012 at 20:31
  • If using this code please add \setlength\extrarowheight{3pt} before the table to avoid causing pain to @barbarabeeton Commented Nov 17, 2012 at 20:40
  • 1
    Ah so @barbarabeeton will be able to sleep easily tonight:-) Commented Nov 17, 2012 at 20:56
  • 2
    Wonderful to see Jupiter arguing with Minerva here on TeX.SE... Commented Nov 18, 2012 at 10:44
5

A half-baked pgfplotstable solution. The column sums are missing but sanity check on the sums of rows are implemented (gives the stupid error in the screenshot if there is a discrepancy). Also the upper left corner text is optional you can change it when entering the table. With this you don't need to enter your data in a tabular format.

\documentclass{article} \usepackage{pgfplotstable,multirow,booktabs} \pgfplotstableset{toughtable/.style={ every head row/.style={before row={\toprule \multicolumn{2}{c}{\multirow{2}{*}{\textbf{#1}}} &\multicolumn{2}{c}{Type} &\multicolumn{2}{c}{Size} &\multirow{2}{*}{All}\\ }, after row=\midrule }, every last row/.style={after row=\bottomrule}, create on use/myfirstcol/.style ={create col/set list={Good,Ugly,,,Bad,\textbf{TOTAL}}},%A dummy column create on use/mysecondcol/.style={create col/set list={,Cow,Goat,Horse,}},%A dummy column create on use/summationcol/.style={ create col/expr={\thisrowno{0}+\thisrowno{1}-\thisrowno{2}-\thisrowno{3}==0?\thisrowno{0}+\thisrowno{1}:0} }, columns={myfirstcol,mysecondcol,[index]0,[index]1,[index]2,[index]3,summationcol}, columns/myfirstcol/.style={string type,column name=, assign cell content/.code={% \ifnum\pgfplotstablerow=1\pgfkeyssetvalue{/pgfplots/table/@cell content}{\multirow{3}{*}{Ugly}}\fi } }, columns/mysecondcol/.style={string type,column name=}, columns/summationcol/.style={string type,column name=, assign cell content/.code={ \pgfmathparse{\pgfkeysvalueof{/pgfplots/table/@preprocessed cell content}==0?int(1):int(0)} \ifnum\pgfmathresult=1\relax \pgfkeyssetvalue{/pgfplots/table/@cell content}{Chicken Run!!}% \else \pgfmathparse{int(\pgfkeysvalueof{/pgfplots/table/@unprocessed cell content})} \edef\temp{\noexpand\pgfkeyssetvalue{/pgfplots/table/@cell content}{\pgfmathresult}}\temp \fi } }, display columns/2/.style={column name=A}, display columns/3/.style={column name=B}, display columns/4/.style={column name=Big}, display columns/5/.style={column name=Small}, every row no 1/.style={before row=\hline,after row=\cmidrule{2-7}}, every row no 2/.style={after row=\cmidrule{2-7}}, every row no 3/.style={after row=\hline}, every row no 4/.style={after row=\hline}, } } \begin{document} \pgfplotstabletypeset[toughtable=NUMBERS]{ 1 4 2 3 7 1 3 4 1 2 0 3 2 1 3 0 12 1 6 7 } \end{document} 

enter image description here

I'll try to get the columns sum hopefully soon.

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.