-1

Ich bin auf der Suche nach einer Möglichkeit aus einer Datei folgender Struktur

1,a
2,a
2,a
2,a
3,a
3,a
4,a
4,a
4,a
4,a
5,a
5,a
6,a
6,a
7,a

folgendes zu machen

1 1
2 3
3 2
4 4
5 2
6 2
7 1

(Das A dient nur dazu um zu zeigen, dass es mehrere spalten geben kann...

ICh denke an das package datatool, aber ich kann das irgendwie nicht umsetzen, meine versuche basieren auf folgenden überlegungen....

datenbank laden.... in der datenbank nach dem minimum suchen counter erhöhen, zeile löschen bis die datenbank das erste mal durch ist.... dann neue zeile in neuer datenbank.... und den counter übertragen....

dann die prozedurer wieder von vorne, bis die anzahl der daten null sind....

ergebnisdatenbank sortieren...hm....

an der Umsetzung scheitert es; ich schaffe es nicht zwei ineinander geschachtelte for schleifen innerhalb von datatool zu realisieren...

LG Goldnas

2
6
\documentclass{article}
\usepackage{datatool}
\usepackage{filecontents}
\begin{filecontents*}{\jobname.csv}
1,a
2,a
2,a
2,a
3,a
3,a
4,a
4,a
4,a
4,a
5,a
5,a
6,a
6,a
7,a
\end{filecontents*}

\DTLloaddb[noheader,keys={num}]{raw}{\jobname.csv}

\DTLnewdb{hist}
\newcounter{numcnt}

% fill table "hist"
\newcommand*{\SaveRow}{%
  \ifnum\value{numcnt}>0 %
    \DTLnewrow{hist}%
    \begingroup
      \dtlexpandnewvalue
      \DTLnewdbentry{hist}{num}{\oldnum}%
      \DTLnewdbentry{hist}{count}{\the\value{numcnt}}%
    \endgroup
  \fi
}%
\newcommand*{\oldnum}{}%
\setcounter{numcnt}{0}%
\DTLforeach*{raw}{\num=num}{%
  \ifx\oldnum\num
    \stepcounter{numcnt}%
  \else
    \SaveRow
    \setcounter{numcnt}{1}%
    \let\oldnum\num
  \fi
}%
\SaveRow

% write table "hist" with header
\DTLsetdelimiter{,}
\DTLsavedb{hist}{\jobname.hist}

\begin{document}   
Hello World% nothing would be written without output page
\end{document}

Result is database hist or the file \jobname.hist:

num,count
1,1
2,3
3,2
4,4
5,2
6,2
7,1

Remarks:

  • When writing a file, package datatool does not use \immediate, therefore a database file is writen at the next output of a page and is not written at all after the last page.

Variation, writing file \jobname.hist without headers:

\documentclass{article}
\usepackage{datatool}
\usepackage{filecontents}
\begin{filecontents*}{\jobname.csv}
1,a
2,a
2,a
2,a
3,a
3,a
4,a
4,a
4,a
4,a
5,a
5,a
6,a
6,a
7,a
\end{filecontents*}

\DTLloaddb[noheader,keys={num}]{raw}{\jobname.csv}

\DTLnewdb{hist}
\newcounter{numcnt}

% fill table "hist" and manually write it
\makeatletter
\immediate\openout\@dtl@write=\jobname.hist\relax
% reusing datatool's write handle
\newcommand*{\SaveRow}{%  
  \ifnum\value{numcnt}>0 %
    \DTLnewrow{hist}%
    \begingroup
      \dtlexpandnewvalue
      \DTLnewdbentry{hist}{num}{\oldnum}%
      \DTLnewdbentry{hist}{count}{\the\value{numcnt}}%
      \immediate\write\@dtl@write{\oldnum,\the\value{numcnt}}%
    \endgroup
  \fi
}%
\newcommand*{\oldnum}{}%
\setcounter{numcnt}{0}%
\DTLforeach*{raw}{\num=num}{%
  \ifx\oldnum\num
    \stepcounter{numcnt}%
  \else
    \SaveRow
    \setcounter{numcnt}{1}%
    \let\oldnum\num
  \fi
}%
\SaveRow
\immediate\closeout\@dtl@write
\makeatother

\begin{document}
\end{document}

Again the result is database hist and file \jobname.hist, but this time the file is written without headers:

1,1
2,3
3,2
4,4
5,2
6,2
7,1

Remarks:

  • The (internal) write handle of package datatool is reused, because write handles are a very limited resource.
  • The data base is written immediately (\immediate\write) and not delayed to the next page output.

Not the answer you're looking for? Browse other questions tagged or ask your own question.