1

I would like to use siunitx package to merge data/uncertainty pairs available from an external file (using precision and rounding options as shown).

It seems like the content of the variable (both defined using def) is different if initialised using a hard-coded number or read from a table (pgfplotstable); as the latter breaks the code (see last commented line).

\documentclass{article}
\usepackage{pgfplotstable}
\usepackage{siunitx}
\sisetup{drop-zero-decimal,round-mode=uncertainty,round-precision=1,uncertainty-mode=separate}

\begin{document}

\pgfplotstableread{
    x   dx
    10.1    0.02
    21.2    4.1
    32.3    0.6
}\loadedtable
%\pgfplotstabletypeset[columns={x,dx}]\loadedtable
\vspace{1cm}

\def\varTableA{\pgfplotstablegetelem{0}{x}\of{\loadedtable}\pgfplotsretval}
\def\varTableB{\pgfplotstablegetelem{0}{dx}\of{\loadedtable}\pgfplotsretval}

\def\varA{10.1}
\def\varB{0.02}

% What I would like to do, using values obtained from a table (external file) instead of hard coded values.
\num{10.1 +- 0.02} \\ % Gives the desired output
\num{\varA +- \varB}  % Gives the desired output

% One verifies that the variables contain the correct value -> all good
\varA \qquad \varTableA \\ % Gives 10.1 and 10.1
\varB \qquad \varTableB \\ % Gives 0.02 and 0.02

% Using `parse-numbers=false` is not an option
%\num{\varTableA +- \varTableB} % Doesn't work

\end{document}
3
  • \pgfplotstablegetelem{0}{x}\of{\loadedtable}\let\varTableA\pgfplotsretval or use \pgfplotsretval directly inside siunitx' commands. Feb 18 at 3:01
  • Thanks, that works perfectly! Do you know "why" it didn't work using \def? Maybe you can write your comment as an answer for me to validate it.
    – Mammouth
    Feb 18 at 11:42
  • Since \pgfplotstableretval is defined using \edef, any resulting \def will not be expandable. Feb 18 at 14:49

1 Answer 1

0

(La)TeX is not a programming language and

\def\macro{\pgfplotstablegetelem{0}{x}\of{\loadedtable}}
% or even
\def\macro{\pgfplotstablegetelem{0}{x}\of{\loadedtable}\pgfplotsretval}

is not the same as

double variable = myTable.getRow(0).getColumn("x").getValue();

You can't usually \def or \edef a macro to something that may typeset the correct content onto the page and assume said macro to be just the text of that output.

The line

\pgfplotstablegetelem{0}{x}\of{\loadedtable}\pgfplotsretval

does two distinctive things:

  1. Just

    \pgfplotstablegetelem{0}{x}\of{\loadedtable}
    

    defines \pgfplotsretval to be the content of row 0 and column x (here 10.1).

  2. Then you call

    \pgfplotsretval
    

    and that will expand to its content.

    If it's just somewhere around normal text it will output this onto the page.

    If used as

    \num{\pgfplotsretval}
    

    the siunitx package will process it somehow and maybe print something totally different onto the page (here it adds a zero: 10.10).

The \num macro of siunitx expects only numbers in its argument (unless parse-numbers = false). However, you feed it the whole \pgfplotstablegetelem expansion. And that's just not a raw number for a multitude of reasons.


You will need to do \pgfplotstablegetelem outside of any siunitx macros and either use \pgfplotsretval directly in a \num (not possible here because you need two of those) or

  • \edef\varTableA{\pgfplotsretval} or
  • \let\varTableA\pgfplotsretval.

If you need this more often I suggest a macro like \pgfplotstableelem as I did in the code below.


Note: The pgfplotstable manual states about \pgfplotstablegetelem:

If possible, avoid using this command inside of loops. It is quite slow.

This is not a problem in this small example but depending on your real use-case there might be better ways to read and typeset the contents of your table.

Code

\documentclass{article}
\usepackage{pgfplotstable}
\usepackage{siunitx}
\sisetup{
  drop-zero-decimal,
  round-mode       = uncertainty,
  round-precision  = 1,
  uncertainty-mode = separate
}
\pgfplotstableread{
    x   dx
    10.1    0.02
    21.2    4.1
    32.3    0.6
}\loadedtable
\def\pgfplotstableelem#1\to#2{%
  \pgfplotstablegetelem#1\let#2\pgfplotsretval}
\begin{document}
%\pgfplotstabletypeset[columns={x,dx}]\loadedtable
%\vspace{1cm}

\pgfplotstableelem{0}{x}\of{\loadedtable}\to{\varTableA}
\pgfplotstableelem{0}{dx}\of{\loadedtable}\to{\varTableB}

\def\varA{10.1}
\def\varB{0.02}

% What I would like to do, using values obtained from a table (external file) instead of hard coded values.
\num{10.1 +- 0.02} \\ % Gives the desired output
\num{\varA +- \varB}  % Gives the desired output

% One verifies that the variables contain the correct value -> all good
\varA \qquad \varTableA \\ % Gives 10.1 and 10.1
\varB \qquad \varTableB \\ % Gives 0.02 and 0.02

% Using `parse-numbers=false` is not an option
\num{\varTableA +- \varTableB} % ← !
\end{document}

You must log in to answer this question.

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