Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

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}
share|improve this question

1 Answer 1

up vote 3 down vote accepted

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}
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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