pgfplotstable
是否可以根据多个键对行进行排序?
例如输入文件如下:
Mtx Kind P Sp
A LP 16 4.2
C OPT 16 72.5
A LP 64 20.3
B OPT 16 5.7
B OPT 64 16.4
A LP 256 90.4
我们希望Kind
先按列排序,然后按Mtx
,再按P
。所需表格应如下所示:
Mtx Kind P Sp
B OPT 16 5.7
B OPT 64 16.4
C OPT 16 72.5
A LP 16 4.2
A LP 64 20.3
A LP 256 90.4
我可以对多个数字列进行排序。但是,由于我无法将字符串转换为数值(例如通过使用字符串哈希),因此我无法对此类数据进行排序。也可以直接使用多个键对文件进行排序,而无需使用pgfplotstable
。
答案1
Pgfplots 内置了对单一排序键的支持。
但是,如果可以插入多个排序键,则需要付出一些努力和了解一些内部知识:
\documentclass[a4paper]{standalone}
\usepackage{pgfplots}
\usepackage{pgfplotstable}
\begin{document}
\def\pgfplotsinvokeiflessthan#1#2#3#4{%
\pgfkeysvalueof{/pgfplots/iflessthan/.@cmd}{#1}{#2}{#3}{#4}\pgfeov
}%
\def\pgfplotsmulticmpthree#1#2#3#4#5#6\do#7#8{%
\pgfplotsset{string <}%
\pgfplotsinvokeiflessthan{#1}{#4}{%
% first key <:
#7%
}{%
\pgfplotsinvokeiflessthan{#4}{#1}{%
% first key >:
#8%
}{%
% first key ==:
\pgfplotsset{string <}%
\pgfplotsinvokeiflessthan{#2}{#5}{%
% second key <
#7%
}{%
\pgfplotsinvokeiflessthan{#5}{#2}{%
% second key >
#8%
}{%
% second key ==
\pgfplotsset{float <}%
\pgfplotsinvokeiflessthan{#3}{#6}{%
% third key <
#7%
}{%
% third key >=
#8%
}%
}%
}%
}%
}%
}%
\pgfplotstabletypeset[
create on use/sortkey/.style={
create col/assign/.code={%
\edef\entry{{\thisrow{Kind}}{\thisrow{Mtx}}{\thisrow{P}}}%
\pgfkeyslet{/pgfplots/table/create col/next content}\entry
}
},
sort key=sortkey,
sort cmp={%
iflessthan/.code args={#1#2#3#4}{%
\edef\temp{#1#2}%
\expandafter\pgfplotsmulticmpthree\temp\do{#3}{#4}%
},
},
sort,
columns/Mtx/.style={string type},
columns/Kind/.style={string type},
]{
Mtx Kind P Sp
A LP 16 4.2
C OPT 16 72.5
A LP 64 20.3
B OPT 16 5.7
B OPT 64 16.4
A LP 256 90.4
}
\end{document}
该方法由两部分组成:(1)创建一个名为的临时列,sortkey
该列将第一行扩展为{A}{LP}{16}
;(2)定义自定义的sort cmp
。此处的自定义sort cmp
使用多键比较(字典顺序比较)string <
对前两个键使用 ,float <
对第三个键使用 。
请注意,在定义定制的比较时实例sort key=sortkey
化规范。create on use
sort cmp
该键sort
激活排序功能
这种方法相当通用,可能应该成为一种通用实用程序;我会考虑一种合适的预定义样式。