6

I try to calculate the values of a new column errorxin a pgfplotstable on the fly with \pgfplotstableset{create on use... based on the colums error1 and error2 as error1 - error2.

This works fine, if I do not have missing values. Some of the values of error1 may be missing (the data contains "NA" instead of a number). In this case, the new column errorx should contain error2.

How can I do that?

I tried to use \IfDecimal from the xstring package, but that fails.

Here is an example based on code from the pgfplotstable manual:

\documentclass{article}
\usepackage{xstring}
\usepackage{pgfplotstable}

\begin{document}

% Alternative: inline table data:
\pgfplotstableread{
level   dof     error1 error2 info      grad(log(dof),log(error2))      quot(error1)
1       4       NA             7.57858283e-01 48        0                   0
2       16      6.25000000e-02 5.00000000e-01 25        -3.00000000e-01 4
3       64      1.56250000e-02 2.87174589e-01 41        -3.99999999e-01 4
4       256     3.90625000e-03 1.43587294e-01 8         -5.00000003e-01 4
5       1024    9.76562500e-04 4.41941738e-02 22        -8.49999999e-01 4
6       4096    2.44140625e-04 1.69802322e-02 46        -6.90000001e-01 4
7       16384   6.10351562e-05 8.20091159e-03 40        -5.24999999e-01 4
8       65536   1.52587891e-05 3.90625000e-03 48        -5.35000000e-01 3.99999999e+00
9       262144 3.81469727e-06 1.95312500e-03 33         -5.00000000e-01 4.00000001e+00
10      1048576 9.53674316e-07 9.76562500e-04 2         -5.00000000e-01 4.00000001e+00
}\loadedtable

% fails with
% ERROR: Package PGF Math Error: Unknown function `NA' (in 'NA-7.57858283e-01 ').
\pgfplotstableset{create on use/error12/.style={
    create col/expr={\thisrow{error1}-\thisrow{error2}
    }
  }
}


% fails with
% ERROR: Undefined control sequence.
% 
% --- TeX said ---
% \@xs@IfDecimal@@ ...@xs@arg@i {#1}\edef \@xs@call 
%                                                   {\noexpand \@xs@IfDecimal ...
% l.38 ...etypeset[columns={dof,errorx}]\loadedtable
\pgfplotstableset{create on use/errorx/.style={
    create col/expr={\IfDecimal{\thisrow{error1}}{\thisrow{error1}-\thisrow{error2}}{\thisrow{error2}}
    }
  }
}


\pgfplotstabletypeset[columns={dof,error12}]\loadedtable
\hspace{2cm}
\pgfplotstabletypeset[columns={dof,errorx}]\loadedtable

\end{document}

1 Answer 1

4

You can't use create col/expr here, because that passes its argument straight to the math parser. Instead, you'll have to work with \pgfplotstablecreatecol and the create col/assign/.code key, which allows you to execute arbitrary code for each cell. It expects you to set the key /pgfplots/table/create col/next content to the desired value of the cell

To create a column like you described, you could say

\pgfplotstablecreatecol[
    create col/assign/.code={%
        \pgfkeys{/pgf/fpu=true}
        \getthisrow{error1}\entry
        \ifnum\pdfstrcmp{\entry}{NA}=0
            \pgfmathparse{\thisrow{error2}}
        \else
            \pgfmathparse{\thisrow{error1}-\thisrow{error2}}
        \fi
        \pgfkeyslet{/pgfplots/table/create col/next content}\pgfmathresult
    }
]{errorx}\loadedtable

\documentclass{article}
\usepackage{xstring}
\usepackage{pgfplotstable}

\begin{document}

% Alternative: inline table data:
\pgfplotstableread[string replace={NA}{-9999}]{
level   dof     error1 error2 info      grad(log(dof),log(error2))      quot(error1)
1       4       NA            7.57858283e-01 48        0                   0
2       16      6.25000000e-02 5.00000000e-01 25        -3.00000000e-01 4
3       64      1.56250000e-02 2.87174589e-01 41        -3.99999999e-01 4
4       256     3.90625000e-03 1.43587294e-01 8         -5.00000003e-01 4
5       1024    9.76562500e-04 4.41941738e-02 22        -8.49999999e-01 4
6       4096    2.44140625e-04 1.69802322e-02 46        -6.90000001e-01 4
7       16384   6.10351562e-05 8.20091159e-03 40        -5.24999999e-01 4
8       65536   1.52587891e-05 3.90625000e-03 48        -5.35000000e-01 3.99999999e+00
9       262144 3.81469727e-06 1.95312500e-03 33         -5.00000000e-01 4.00000001e+00
10      1048576 9.53674316e-07 9.76562500e-04 2         -5.00000000e-01 4.00000001e+00
}\loadedtable


\pgfplotstablecreatecol[
    create col/assign/.code={%
        \pgfkeys{/pgf/fpu=true}
        \getthisrow{error1}\entry
        \ifnum\pdfstrcmp{\entry}{NA}=0
            \pgfmathparse{\thisrow{error2}}
        \else
            \pgfmathparse{\thisrow{error1}-\thisrow{error2}}
        \fi
        \pgfkeyslet{/pgfplots/table/create col/next content}\pgfmathresult
    }
]{errorx}\loadedtable

\pgfplotstabletypeset[columns={dof,errorx}]\loadedtable

\end{document}

You must log in to answer this question.

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