# siunitx, brackets around negative numbers

writing tables with statistics result often contain negative numbers in brackets, for example (-1.23), which should be aligned on the decimal point with other numbers in columns. this can be (simply) accomplished by Scolumn option parse-numbers=false, however this option disables most of the other options of the S column (see first example in mwe below)

another possibilities, which cross my mind is defined robust command, for example \brckt and use it instead of (. this approach works fine, i.e. preserve all S column options (see the second example in mwe), however i wonder, if any one know for better solution. so far my search on this site did not yield to better solution.

the (not so) minimal working example:

\documentclass{article}
\usepackage{booktabs, threeparttable}
\usepackage{siunitx}

\usepackage{etoolbox}                      % used in second example
\newrobustcmd{\brckt}{(}

\begin{document}
\begin{center}
\sisetup{input-symbols = {( )},             % has no sense
table-space-text-pre={(},          % has no effect ...
table-align-text-pre=false,        % has no effect ...
table-space-text-post={$^{***}$},  % has no effect ...
table-align-text-post=false,       % has no effect ...
round-mode = places,               % has no sense
%         round-precision = 3               % make error
parse-numbers=false,               % <---
}
\begin{threeparttable}[htb]
\caption{first example}
\label{tab:statistic}
\begin{tabular}{*{3}{S[table-format=-2.3]}}% integer part had to have
% one digit more than normally needed
% other vice decimal point is overwritten
\toprule
1.23\tnote{*}   & 1.234 \tnote{**}  & 1.2345\tnote{***} \\
(9.87)          &   (-7.89)         &   (-7.89)         \\
\bottomrule
\end{tabular}
\begin{tablenotes}[para]
\item[*]    text;
\item[**]   text;
\item[**]   text.
\end{tablenotes}
\end{threeparttable}
\end{center}

\begin{center}
\sisetup{input-symbols = {( - )},
table-space-text-pre={(},
table-align-text-pre=false,
table-space-text-post={$^{***}$},
table-align-text-post=false,
round-mode = places,
round-precision = 3
}
\begin{threeparttable}[htb]
\caption{second example}
\label{tab:statistic}
\begin{tabular}{*{3}{S[table-format=-1.3]} }
\toprule
1.23\tnote{*}   & 1.234 \tnote{**}  & 1.2345\tnote{***} \\
(9.87)          & \brckt-7.89)      & \brckt-7.89)      \\
\bottomrule
\end{tabular}
\begin{tablenotes}[para]
\item[*]    text;
\item[**]   text;
\item[**]   text.
\end{tablenotes}
\end{threeparttable}
\end{center}
\end{document}


• What's the difference between the tables (except a typo for the number in the last cell of the first row)? – Bernard Sep 8 '18 at 21:45
• @Bernard, as i say in the question: in the first example is not possible to use the most of S column options (since they are disabled -- as expected -- by parse-numbers=false). the problem is, how to obtain for example (-1.234) and preserve S column options for number formatting. not using parse-numbers=false cause error. in second example i try to avoid it by defining robust command for (, but solution is somehow rude. – Zarko Sep 8 '18 at 21:52

Based on an answer I recently gave at Specifying minimal (not fixed) width in tabular, that was capable of aligning at decimal points (without using siunitx), I took that code and significantly extended it to allow for parentheses and \tnotes (only ) and \tnotes may appear after the decimal point!). The extended code also performs numerical rounding (in native LaTeX).

The method creates a D{} column, with the argument denoting the number of digits allowed to follow the decimal point.

Again, I stress that this method operates outside of siunitx, and so the only features it provides are limited to decimal alignment, surrounding the numerical arguments in parens, and the use of a trailing \tnote.

\documentclass{article}
\usepackage{array,stackengine,collcell,booktabs,threeparttable}
\let\endecm\relax
\newcolumntype{D}[1]{%
>{\catcode)=\active \collectcell\Decm l{#1}}r<{..\endDecm\endcollectcell}}
\def\decm#1#2#3.#4.#5\endDecm{%
$#3.$%
\ensurestackMath{\stackengine%
{0pt}{\truncdig{#4}{#2}}{\rule{#2\wd0}{0pt}}{O}{#1}{F}{F}{L}}}
\newcommand\Decm[1]{\let\tnote\specialtnote\setbox0=\hbox{0}\decm#1}
\newcommand\specialtnote[1]{\rlap{$^{#1}$}}
\let\svrp)
{\catcode)=\active
\gdef){\rlap{\svrp}}
}
\newcommand\truncdig[2]{\truncdigaux{#2}#1\relax\relax}
\def\truncdigaux#1#2#3\relax{%
\ifx\tnote#2#2{#3}\else
\if\svrp\detokenize{#2}\rlap{)}\else
\ifnum#1>1\relax
#2%
\else
\ifnum#1>0\relax
\roundit#2#3\relax\relax
\fi
\fi
\fi
\ifx\relax#3\else
\expandafter\truncdigaux\expandafter{\the\numexpr#1-1\relax}#3\relax
\fi
\fi
}
\def\roundit#1#2#3\relax{
\ifx\tnote#2#1\else
\ifx\relax#2#1\else
\if\svrp\detokenize{#2}#1\else
\expandafter\ifnum\expandafter\detokenize\expandafter{#2}<53\relax#1\else
\expandafter\ifnum\expandafter\detokenize\expandafter{#2}>57\relax#1\else
\the\numexpr#1+1%
\fi
\fi
\fi
\fi
\fi
}
\begin{document}
\tabcolsep=15pt\relax
\begin{tabular}{D{2}D{3}D{3}}
\toprule
1.23\tnote{*}   & 1.234 \tnote{**}  & 1.2345\tnote{***} \\
(9.87)          &   (-7.89)         &   (-7.89)         \\
13.375          &   (-43.2759)         &   1.234         \\
\bottomrule
\end{tabular}
\begin{tablenotes}[para]
\item[*]    text;
\item[**]   text;
\item[**]   text.
\end{tablenotes}
\end{document}


The following table, asking for columns with 2, 3, and 3 post-decimal digits, is thus produced from these inputs:

1.23\tnote{*}   & 1.234 \tnote{**}  & 1.2345\tnote{***} \\
(9.87)          &   (-7.89)         &   (-7.89)         \\
13.375          &   (-43.2759)         &   1.234         \\


• thank you very much for answer! nice workaround (+1) , however, as you point out yourself, it not use ˙siunitx˙ (unfortunately). i expect that required robustness for ( will be solved on more elegant way as i show in question or even be incorporated to siunitx` package (since such tables are quite common). – Zarko Mar 14 at 17:07
• @Zarko I knew as much going in, but my recollection of my earlier approach seemed too good to pass up. Mostly, I wanted to see if I could make a go of it. – Steven B. Segletes Mar 14 at 21:51