7

Almost too easy:

I have two databases "First" and "Second", both get their data from tab-delineated files "First.txt" and "Second.txt"

Both contain two columns ('year' and 'number') and an equal amount of rows!

This code :

\begin{document}

\catcode`\^^I=12 %
\DTLsetseparator{   }%

\DTLloaddb{First}{First.txt}
\DTLloaddb{Second}{Second.txt}

\begin{table}[htbp]
\caption{First}
\centering
\DTLdisplaydb{First} 
\end{table}

\begin{table}[htbp]
\caption{Second}
\centering
\DTLdisplaydb{Second} 
\end{table}

\end{document}

creates two separate tables, but I am trying to make a table containing three columns: year, number (from First), number (from Second).

I know it sounds trivial (and probably is)... but I am stuck.

Anyone any idea?

2 Answers2

5

Here's a way of appending the second column of the second database to the first database. (I've used comma-separated values rather than tab separated for simplicity, but you can changed that as required.) This assumes that both databases have their rows in the same order (on the first column).

\documentclass{article}

\usepackage{datatool}

% generate first test database
\begin{filecontents}{first.csv}
Year,Number
2001,10
2002,20
2003,30
2004,40
\end{filecontents}

% generate second test database
\begin{filecontents}{second.csv}
Year,Number
2001,101
2002,202
2003,303
2004,404
\end{filecontents}

\DTLloaddb{first}{first.csv}
\DTLloaddb{second}{second.csv}

\begin{document}

% append second column of second data base to first data base

\newcount\rowIdx

\dtlforcolumn{\secondNumber}{second}{Number}%
{%
  % iterate through each entry in the `Number' column of the second database
  \advance\rowIdx by 1\relax
  % get corresponding row of first database
  \dtlgetrow{first}{\rowIdx}%
  % append to current row (this new column is assigned the key `Number2')
  \dtlappendentrytocurrentrow{Number2}{\secondNumber}%
  % update first database
  \dtlrecombine
}

\DTLdisplaydb{first}

\end{document}

The result looks like:

Image of result

Nicola Talbot
  • 41,153
  • Brilliant! Just what I hoped! (Your answer made me realise that I needed to upgrade my TexLive installation, but then I couldn't wait and so I did an install of the datatool.dtx and .ins directly.) Your solution can easily be extended to situations when I need to append more than one column. Thanks a lot Nicola! – brvbogae Jun 05 '13 at 17:47
2

This uses the readarray package to input the datafiles into "array" data structures (here named first and second). Then those array elements can be regurgitated in the table. The only quirk, for which I used a solution based on that provided by Herbert in How to programmatically make tabular rows using `\whiledo` ?, is that the \whiledo used to construct each row of the table has to be performed outside of the tabular environment. In particular, it is the presence of tab characters & inside the \whiledo inside the tabular that is somehow the problem (resolved by Herbert).

\documentclass{article}
\usepackage{readarray}
\newcounter{index}
  % Based on:
  % https://tex.stackexchange.com/questions/7590/
  % how-to-programmatically-make-tabular-rows-using-whiledo
  \makeatletter
  \newcounter{tabindex}
  \newtoks\@tabtoks
  \newcommand\addtabtoks[1]{%
    \@tabtoks\expandafter{\the\@tabtoks\stepcounter{tabindex}#1}}
  \newcommand*\resettabtoks{\@tabtoks{}}
  \newcommand*\synctabindex[1]{\setcounter{tabindex}{\value{#1}}}
  \newcommand*\printtabtoks{\the\@tabtoks}
  \makeatother
\begin{document}
\readdef{First.txt}{\tmpa}
\readArrayij{\tmpa}{first}{\ncols}
\readdef{Second.txt}{\tmpb}
\readArrayij{\tmpb}{second}{\ncols}
%
\resettabtoks
\setcounter{index}{0}
\synctabindex{index}
\whiledo{\value{index} < \nrows}{%
  \addtocounter{index}{1}%
  \addtabtoks{%
    \arrayij{first}{\thetabindex}{1} &
    \arrayij{first}{\thetabindex}{2} &
    \arrayij{second}{\thetabindex}{2} 
    \ifthenelse{\equal{\thetabindex}{\nrows}}{}{\\}%
  }
}
\begin{tabular}{|c|r|r|}
  \hline
  \printtabtoks
  \\\hline
\end{tabular}
\end{document}

enter image description here