4

I need to tabulate some matrix data of dimensions NxN where N can be 4 to 100. For N>20 (N>35 in landscape) the table must span in several pages. Edit: I forgot to say that the data consists of only real numbers. I would like to have control in producing these numbers wrt their number of digits etc.

I am unsure as to what table package to use, so I am trying to test with some synthetic data. But I have problem creating it, in tabular form.

For example:

\documentclass[a4paper,12pt]{article} \usepackage{lscape} \usepackage{longtable} \usepackage{pgffor} \usepackage{array} \begin{document} \newcommand{\N}{40} % data size % test to see a row is created correctly: % A -> & % N -> \\ \foreach \i in {1,...,\N} { \i=\ifnum\i<\N A \else N \fi } \begin{landscape} \begin{longtable}{*{40}{c|}} \hline % Generate header row \foreach \i in {1,...,\N} { \i \ifnum\i<\N && \else \\ \fi } % <<< line 23 \hline \endfirsthead % % Repeat header on subsequent pages \foreach \i in {1,...,\N} { \i \ifnum\i<\N && \else \\ \fi } \hline \endhead \foreach \i in {1,...,\N} { \foreach \i in {1,...,\N} { 1.2 \ifnum\i<\N && \else \\ \fi } } \end{longtable} \end{landscape} \end{document} 

But, it complains about:

! Missing \endgroup inserted. <inserted text> \endgroup l.23 } 

(line 23 is marked in my code above). I created a row at the beggining to check the correct number of '&' and '\'. Isn't the row correct?

4
  • What about text filler like lipsum or `kantlipsum? Commented Nov 6 at 18:11
  • oops i forgot to say it was numerical (real numbers) data. Anyway, I prefer to have full control as to the number of digits etc of the synthetic data like what I do above, any idea why it throws an error? Commented Nov 6 at 18:32
  • 1
    use more or less any loop macro other than pgf for which is more or less useless for any kind pf programming loop as it places each iteration in a group Commented Nov 6 at 22:20
  • 1
    apart from the fact that pgffor is unsuitable you are adding && each iteration so making 80 columns in a 40 column table. Commented Nov 6 at 22:26

3 Answers 3

4

\foreach isn't a good tool for this job.

\documentclass[a4paper,12pt]{article} \usepackage{lscape} \usepackage{longtable} \usepackage{array} \ExplSyntaxOn \NewExpandableDocumentCommand{\makeheader}{} { \hline \int_step_function:nN {\N} \biiako_test_header:n } \cs_new:Nn \biiako_test_header:n { \int_compare:nTF {#1<\N} {#1 &} {N \\ \hline} } \NewExpandableDocumentCommand{\makebody}{m} {% #1 = number of rows \int_step_function:nN {#1} \biiako_test_row:n } \cs_new:Nn \biiako_test_row:n { \int_step_function:nN {\N} \biiako_test_entry:n } \cs_new:Nn \biiako_test_entry:n { 1.2 \int_compare:nTF {#1<\N} {&} {\\ \hline} } \ExplSyntaxOff \begin{document} \newcommand{\N}{20} % data size \begin{landscape} \begin{longtable}{|*{40}{c|}} % Generate header row \makeheader \endhead \makebody{60} \end{longtable} \end{landscape} \end{document} 

output

1
  • thank you for this, noting your take-no-prisoners exhibition of writing functions/macros. I thought I could keep it simple with the \foreach. I asked above if there is an automated table-splitter. That's what I need really. Commented Nov 6 at 19:04
5

I can't tell what the hangup with the pgffor machinery may be. At any rate, I think you'll get much faster execution if you switch to LuaLaTeX and use Lua's for loops.

enter image description here

Aside: Unless you use a truly tiny font size, I don't see how you can typeset more than ca 45 columns (containing nothing wider than "1.2") on a single landscape-mode page.

% !TEX TS-program = lualatex \documentclass[a4paper,10pt]{article} % use 10pt, not 12pt \usepackage[margin=7mm]{geometry} % set very narrow margins \usepackage{pdflscape,array,longtable} \begin{document} \begin{landscape} % Global parameter: dimesion of matrix \directlua{ N=45 } \setlength\tabcolsep{2pt} % default: 6pt \begin{longtable}{|*{\directlua{tex.sprint(N)}}{c|}} %% Header row \hline \directlua{ for i=1,N do tex.sprint ( i ) if i<N then tex.sprint ( "&" ) else tex.sprint ( "\\\\" ) end end } \hline \endhead %% Footer \hline \endfoot %% Body of table: NxN matrix, %% Note: no '\hline' directives \directlua{ for j=1,N do for i=1,N do tex.sprint ( "1.2" ) if i<N then tex.sprint ( "&" ) else tex.sprint ( "\\\\" ) end end end } \end{longtable} \end{landscape} \end{document} 
4
  • thanks, but i am not ready to move to lualatex. Although the alternative below looks much scarier :) So, you reckon there is no package for handling long rows? I was hoping I could find an automated table-splitter, so as to create 20x20 tables for me for arbitrary table data and float them. Commented Nov 6 at 19:00
  • 1
    @bliako - I thought your concern was with the getting the for loop running properly. Is your real concern about creating tables with more than, say, 20 columns, possibly via some kind of automated table splitting mechanism? If so, you should post a query directly about this subject. Aside: What exactly is keeping you from moving from pdfLaTeX to LuaLaTeX? (LuaLaTeX has been rather stable for more than a decade by now...) Commented Nov 6 at 19:20
  • Well, I am doing this study with the synthetic data in order to find the best table package for 100x100 tables. And I was stuck with the forloop. Behind the scenes I am using a template system (perl) to produce latex tables. So I have already the power of loops and would prefer not to add another language to the mix. Intially, I wanted to ask a question whether there is a table-splitting package and started preparing some data for demonstrating the long tables. But then I thought perhaps the question will be closed if it was just asking about a package. Anyway, I will ask the question. Commented Nov 6 at 20:48
  • Is there a package to split tables with large number of columns over many pages? tex.stackexchange.com/questions/754525/… Commented Nov 6 at 21:05
3

avoid \pgfor for such tasks it places each iteration in a group which makes it unsuitable for tables.

Also you only need a single & you are generating twice as many columns as you had declared.

A simple recursive macro will generate a row and a similar macro will repeat the rows to complete the table.

enter image description here

\documentclass[a4paper,12pt]{article} \usepackage{lscape} \usepackage{longtable} \usepackage{array} \newcount\myrow \newcount\mycol \begin{document} \def\amp{&} \newcommand{\N}{40 } % data size (needs space) \def\makerow{.\global\advance\mycol1 \ifnum\mycol<\N \amp\expandafter\makerow\fi} \def\makerows{\global\mycol=1 \makerow\global\advance\myrow1 \ifnum\myrow<\N \\ \expandafter\makerows\fi} \begin{landscape} \tiny \begin{longtable}{|*{40}{c|}} \hline % Generate header row \global\mycol=1 \makerow\\ \hline \endfirsthead % \global\mycol=1 \makerow\\ \hline \endhead \global\myrow=1 \makerows\\ \hline \end{longtable} \end{landscape} \end{document} 
1
  • +1 for "avoid \pgffor for such tasks". :-) Commented Nov 7 at 6:22

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.