11

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}

enter image description here

2
  • What's the difference between the tables (except a typo for the number in the last cell of the first row)?
    – Bernard
    Sep 8, 2018 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, 2018 at 21:52

1 Answer 1

2

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         \\

enter image description here

3
  • 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, 2019 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. Mar 14, 2019 at 21:51
  • On related recent question I upvoted you :-)
    – Sebastiano
    Oct 5, 2021 at 20:15

You must log in to answer this question.

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