3

I have following CSV file:

Type    Desc    A   B
A       Site-A  1   2
A       Site-A  2   3
A       Site-B  1   2
A       Site-C  2   3
B       Site-A  1   2
B       Site-A  2   3
B       Site-B  1   2
B       Site-C  2   3

I need to typeset separate (sub)tables using pgfplotstable in the following way:

Table type: A

Desc    A   B
Site-A  1   2
Site-A  2   3
Site-B  1   2
Site-C  2   3

Tabel type B:

Desc    A   B
Site-A  1   2
Site-A  2   3
Site-B  1   2
Site-C  2   3

Where each (sub)table consist from filtered rows with same value (of first column) and this value have to be printed in "subtable" header (along with other text headers).

I'm sorry, but I have no MWE for this case :(

2

1 Answer 1

2

Even though it has been some time I hope someone can still use the answer.

I had the same problem and developed a function for pgfplotstable that filters tables. The complete Code can be found here.

In short, I wrote a function that filters a table (either from file, already loaded or inline) and writes the filtered table to a new macro.

Here is the code along with some helpers.

Beware:

  • the \pgfplotslistpopfrontorrelax macro uses internal macros from pgfplotslist and is thus subject to break upon internal changes (although no such change to pgfplotslist happened in the last 10 years)
  • the performance could be better. Please look at the github referenced above. I might update the code to include better performance and more/more flexible filters.

Helper:

\long\def\pgfplotslistpopfrontorrelax#1\to#2{%
        \pgfplotslistcheckempty#1\relax
        \ifpgfplotslistempty
                \let#2=\relax
        \else
                \expandafter\pgfplotslistpopfront@impl#1\pgfplotslistpopfront@macronames#1#2%
        \fi
}

Code:

\pgfkeys{/pgfplots/table/filter/.code args={#1 #2 #3}{%
        \def\equals{equals}\def\notequal{unequal}%
        \def\given{#2}
        \ifx\given\equals
                \pgfplotstable@filter@equalsfalse
        \else\ifx\given\notequal
                \pgfplotstable@filter@equalstrue
        \else
                \pgfplotsthrow{invalid argument}{#2}{Valid comparators are `\equals` and `\notequal`. You supplied `#2`}\pgfeov%
        \fi\fi
        \def\pgfplotstable@filter@col{#1}%
        \def\pgfplotstable@filter@value{#3}%
}}

%Copy from 2 to 3 and filter by rules in #1
\long\def\pgfplotstablefilter[#1]#2#3{%
        \pgfplotstable@isloadedtable{#2}{%
                \pgfkeys{/pgfplots/table/filter=#1}%
                \pgfplotslistnewempty{\removerows}%
                \pgfplotstableforeachcolumnelement{\pgfplotstable@filter@col}\of#2\as\cell{%
                        \ifx\pgfplotstable@filter@value\cell
                                \ifpgfplotstable@filter@equals
                                        \expandafter\pgfplotslistpushback\pgfplotstablerow\to\removerows
                                \fi
                        \else
                                \ifpgfplotstable@filter@equals\else
                                        \expandafter\pgfplotslistpushback\pgfplotstablerow\to\removerows
                                \fi
                        \fi
                        \let#3=#2%
                        \pgfplotstablegetname#2\pgfplotstable@loc@TMPa
                        \expandafter\let\csname\string#3@@table@name\endcsname=\pgfplotstable@loc@TMPa
                        \expandafter\edef\csname\string#3@@table@scanline\endcsname{\pgfplotstablescanlinelengthof{#2}}%
                        \pgfplotslistforeachungrouped#2\as\pgfplotstable@loc@TMPa{%
                                        \pgfplotslistcopy\removerows\to\removerows@local
                                        \pgfplotslistnewempty\pgfplotstable@loc@TMPc
                                        \pgfplotslistpopfrontorrelax\removerows@local\to\nextremove
                                        \def\currow{0}%
                                        \expandafter\pgfplotslistforeachungrouped\csname\string#2@\pgfplotstable@loc@TMPa\endcsname\as\pgfplotstable@loc@TMPb{%
                                                \ifx\currow\nextremove
                                                        \pgfplotslistpopfrontorrelax\removerows@local\to\nextremove
                                                \else
                                                        \expandafter\pgfplotslistpushback\pgfplotstable@loc@TMPb\to\pgfplotstable@loc@TMPc
                                                \fi
                                                \pgfplotsutil@advancestringcounter\currow
                                        }%
                                        \expandafter\let\csname\string#3@\pgfplotstable@loc@TMPa\endcsname=\pgfplotstable@loc@TMPc
                        }%
                }%
        }{%Table 2 not yet loaded
                \pgfplotstableread{#2}\pgfplotstable@tmptbl
                \pgfplotstablefilter[#1]{\pgfplotstable@tmptbl}{#3}%
        }%
}

Usage:

\documentclass{standalone}

\usepackage{pgfplotstable}
\usepackage{pgfplotstablefilter}

\usepackage{filecontents}
\begin{filecontents}{test.csv}
Type    Desc    A   B
A       Site-A  1   2
A       Site-A  2   3
A       Site-B  1   2
A       Site-C  2   3
B       Site-A  1   2
B       Site-A  2   3
B       Site-B  1   2
B       Site-C  2   3
\end{filecontents}

\pgfplotstableread{test.csv}\mytable

\begin{document}

\pgfkeys{
    /pgfplots/table/.cd,
    columns/Desc/.style={string type},
    columns/Type/.style={string type},
}

\pgfplotstabletypeset[columns/Desc/.style={string type},columns/Type/.style={string type}]{\mytable}\par

\pgfkeys{/pgfplots/table/columns={Desc,A,B}}
\pgfplotstablefilter[Type equals A]{\mytable}{\mytableA}%
\pgfplotstablefilter[Type equals B]{\mytable}{\mytableB}%

\pgfplotstabletypeset{\mytableA}%
\pgfplotstabletypeset{\mytableB}%
\end{document}

Output

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .