6

This is a follow-up for the fantastic question and answer here. I have been struggling with this so long that I would really appreciate help. Say that I have two datasets that are related, but on different scales. It would not be justified to make two tables for them, but it would not work to have the datasets in a same confidence interval graph either. Ideal solution would be to have the data presented in one table with a sub-header like this:
enter image description here

I am, however, experiencing troubles when trying to align these tables. Ideal would be to get them dec sep aligned, but this is not possible using the current approach I have taken based on this question. I suppos I could get better results by directly typing the data into tabular environment, but then I would lose the genius dynamic solution by @Jake. Would anybody know how to get these tables either united or aligned so that they look nice and professional enough for a scientific publication?

Here is the modified code I have used to produce the table above:

\documentclass{article}
\usepackage{booktabs}
\usepackage{multirow}
\usepackage{pgfplotstable}
\usepackage{filecontents}
\usepackage{xspace}
\usepackage{tabularx}

%% The data files
\begin{filecontents}{dataA.txt}
name z p mean lci uci
{\textbf{Variable A}} {}  {}  {}  {}  {}
Afear -0.96  0.33 -0.42 -1.28 0.44
Anofear 0.09 0.93 0.04 -0.85 0.94
B+2 0.29 0.78 0.10 -0.59 0.79
B+1   0.84  0.40  0.30 -0.40 1.00 
B1:1   2.19  0.03  0.80 0.08 1.52 
B-1   1.02  0.31  0.37 -0.33 1.07 
B-2   -0.10  0.92  -0.03 -0.72 0.65 
C+2   -1.11  0.27  -0.30 -0.83 0.23 
C+1   1.15   0.25  0.32 -0.22 0.86 
C1:1   -1.34  0.18  -0.38 -0.93 0.17 
C-1   0.43  0.67  0.12 -0.42 0.66 
\end{filecontents}

\begin{filecontents}{dataB.txt}
name  z p mean  lci uci
{\textbf{Variable B}} {}  {}  {}  {}  {}
C-2 -0.37 0.71  -10 -63 43
D+2 0.41  0.68  12  -44 67
D+1 -0.69 0.49  -20 -77 37
D1:1  -1.33 0.18  -39 -97 19
D-1 -1.21 0.23  -35 -92 22
D-2 0.32  0.75  9 -46 65
E+2 -1.89 0.06  -53 -109  2
E+1 0.78  0.44  23  -34 79
E1:1  0.62  0.53  18  -39 76
E-1 0.17  0.86  5 -52 62
E-2 0.06  0.95  2 -54 57
\end{filecontents}

% Read data files, create new column ``upper CI boundary - mean''
\pgfplotstableread{dataA.txt}\dataA
\pgfplotstableset{create on use/error/.style={
    create col/expr={\thisrow{uci}-\thisrow{mean}
    }
  }
}

\pgfplotstableread{dataB.txt}\dataB
\pgfplotstableset{create on use/error/.style={
    create col/expr={\thisrow{uci}-\thisrow{mean}
    }
  }
}

% Define the command for the plot (I had to do this separately for each dataset)
\newcommand{\errplotA}{%
\begin{tikzpicture}[trim axis left,trim axis right]
\begin{axis}[y=-\baselineskip,
  scale only axis,
  width=6.5cm,
  enlarge y limits={abs=0.5},
  axis y line*=middle,
  y axis line style=dashed,
  ytick=\empty,
  axis x line*=bottom]
% 
% ``mean'' must be present in the datafile, ``error'' is the newly generated column
\addplot+[only marks][error bars/.cd,x dir=both, x explicit]
table [x=mean,y expr=\coordindex,x error=error]{\dataA};
\end{axis}
\end{tikzpicture}%
}

% Exactly the same than above but different dataset
\newcommand{\errplotB}{%
\begin{tikzpicture}[trim axis left,trim axis right]
\begin{axis}[y=-\baselineskip,
  scale only axis,
  width=6.5cm,
  enlarge y limits={abs=0.5},
  axis y line*=middle,
  y axis line style=dashed,
  ytick=\empty,
  axis x line*=bottom]
% 
% ``mean'' must be present in the datafile, ``error'' is the newly generated column
\addplot+[only marks][error bars/.cd,x dir=both, x explicit]
table [x=mean,y expr=\coordindex,x error=error]{\dataB};
\end{axis}
\end{tikzpicture}%
}

\begin{document}
% Get number of rows in datafile
\pgfplotstablegetrowsof{\dataA}
\let\numberofrows=\pgfplotsretval

\begin{table}
\caption{Table caption.}
% Print the table
\pgfplotstabletypeset[column type=,
begin table={\begin{tabularx}{\textwidth}{l X c c c}},
end table={\end{tabularx}},
columns={name,mean,error,z,p},
  % Booktabs rules
  every head row/.style={before row=\toprule,after row=\midrule},
  every last row/.style={after row=[1ex]},
  % Set header name
  columns/name/.style={string type,column name={}},
    % Use the ``error'' column to call the \errplot command in a multirow cell in the first row, keep empty for all other rows
  columns/error/.style={
    column name={$\bar{x} \pm$ 95\% CI},
    assign cell content/.code={% use \multirow for Z column:
    \ifnum\pgfplotstablerow=1
    \pgfkeyssetvalue{/pgfplots/table/@cell content}
    {\multirow{\numberofrows}{6.5cm}{\errplotA}}%
    \else
    \pgfkeyssetvalue{/pgfplots/table/@cell content}{}%
    \fi
    }
  },
  % Format numbers and titles
  columns/mean/.style={column name=$\bar{x}$,fixed,fixed zerofill},
  columns/z/.style={column name=$z$,fixed,fixed zerofill},
  columns/p/.style={column name=$p$,fixed,fixed zerofill},
  ]{\dataA}

  % Second table
  % Get number of rows in datafile
\pgfplotstablegetrowsof{\dataB}
\let\numberofrows=\pgfplotsretval
% Print the table
\pgfplotstabletypeset[column type=,
begin table={\begin{tabularx}{\textwidth}{l X c c c}},
end table={\end{tabularx}},
columns={name,mean,error,z,p},
  % Booktabs rules
  every head row/.style={after row=[1ex]},
  every last row/.style={after row=[3ex]\bottomrule},
  % Set header name
  columns/name/.style={string type,column name={}},
    % Use the ``error'' column to call the \errplot command in a multirow cell in the first row, keep empty for all other rows
  columns/error/.style={
    column name={},
    assign cell content/.code={% use \multirow for Z column:
    \ifnum\pgfplotstablerow=1
    \pgfkeyssetvalue{/pgfplots/table/@cell content}
    {\multirow{\numberofrows}{6.5cm}{\errplotB}}%
    \else
    \pgfkeyssetvalue{/pgfplots/table/@cell content}{}%
    \fi
    }
  },
  % Format numbers and titles
  columns/mean/.style={column name=,fixed,fixed zerofill},
  columns/z/.style={column name=,fixed,fixed zerofill},
  columns/p/.style={column name=,fixed,fixed zerofill},
  ]{\dataB}
\end{table}
\end{document}
4

In this case, I would recommend using the S column type provided by the siunitx package to take care of the alignment. You can specify the number format for the alignment by setting the column type to S[table-format=-2.2], which instructs siunitx to assume that the numbers in the column have a sign and two digits before and after the decimal sign:

\documentclass{article}
\usepackage{booktabs}
\usepackage{multirow}
\usepackage{pgfplotstable}
\usepackage{filecontents}
\usepackage{xspace}
\usepackage{tabularx}
\usepackage{siunitx}

%% The data files
\begin{filecontents}{dataA.txt}
name z p mean lci uci
{\textbf{Variable A}} {}  {}  {}  {}  {}
Afear -0.96  0.33 -0.42 -1.28 0.44
Anofear 0.09 0.93 0.04 -0.85 0.94
B+2 0.29 0.78 0.10 -0.59 0.79
B+1   0.84  0.40  0.30 -0.40 1.00 
B1:1   2.19  0.03  0.80 0.08 1.52 
B-1   1.02  0.31  0.37 -0.33 1.07 
B-2   -0.10  0.92  -0.03 -0.72 0.65 
C+2   -1.11  0.27  -0.30 -0.83 0.23 
C+1   1.15   0.25  0.32 -0.22 0.86 
C1:1   -1.34  0.18  -0.38 -0.93 0.17 
C-1   0.43  0.67  0.12 -0.42 0.66 
\end{filecontents}

\begin{filecontents}{dataB.txt}
name  z p mean  lci uci
{\textbf{Variable B}} {}  {}  {}  {}  {}
C-2 -0.37 0.71  -10 -63 43
D+2 0.41  0.68  12  -44 67
D+1 -0.69 0.49  -20 -77 37
D1:1  -1.33 0.18  -39 -97 19
D-1 -1.21 0.23  -35 -92 22
D-2 0.32  0.75  9 -46 65
E+2 -1.89 0.06  -53 -109  2
E+1 0.78  0.44  23  -34 79
E1:1  0.62  0.53  18  -39 76
E-1 0.17  0.86  5 -52 62
E-2 0.06  0.95  2 -54 57
\end{filecontents}

% Read data files, create new column ``upper CI boundary - mean''
\pgfplotstableread{dataA.txt}\dataA
\pgfplotstableset{create on use/error/.style={
    create col/expr={\thisrow{uci}-\thisrow{mean}
    }
  }
}

\pgfplotstableread{dataB.txt}\dataB
\pgfplotstableset{create on use/error/.style={
    create col/expr={\thisrow{uci}-\thisrow{mean}
    }
  }
}

% Define the command for the plot (I had to do this separately for each dataset)
\newcommand{\errplot}[1]{%
\begin{tikzpicture}[trim axis left,trim axis right]
\begin{axis}[y=-\baselineskip,
  scale only axis,
  width=6.5cm,
  enlarge y limits={abs=0.5},
  axis y line*=middle,
  y axis line style=dashed,
  ytick=\empty,
  axis x line*=bottom]
% 
% ``mean'' must be present in the datafile, ``error'' is the newly generated column
\addplot+[only marks][error bars/.cd,x dir=both, x explicit]
table [x=mean,y expr=\coordindex,x error=error]{#1};
\end{axis}
\end{tikzpicture}%
}

\begin{document}
% Get number of rows in datafile
\pgfplotstablegetrowsof{\dataA}
\let\numberofrows=\pgfplotsretval

\begin{table}
\caption{Table caption.}
% Print the table
\pgfplotstabletypeset[
columns={name,mean,error,z,p},
  % Booktabs rules
  every head row/.style={before row=\toprule, after row=\midrule},
  every last row/.style={after row=[1ex]},
  % Set header name
  columns/name/.style={string type,column name={}},
    % Use the ``error'' column to call the \errplot command in a multirow cell in the first row, keep empty for all other rows
  columns/error/.style={
    column name={$\bar{x} \pm$ 95\% CI},
    assign cell content/.code={% use \multirow for Z column:
    \ifnum\pgfplotstablerow=1
    \pgfkeyssetvalue{/pgfplots/table/@cell content}
    {\multirow{\numberofrows}{6.5cm}{\errplot{\dataA}}}%
    \else
    \pgfkeyssetvalue{/pgfplots/table/@cell content}{}%
    \fi
    }
  },
  % Format numbers and titles
  columns/mean/.style={column name=$\bar{x}$, string type, column type={S[table-format=-2.2]}},
  columns/z/.style={column name=$z$, string type, column type={S[table-format=-1.2]}},
  columns/p/.style={column name=$p$, string type, column type={S[table-format=1.2]}},
  ]{\dataA}

\pgfplotstabletypeset[
columns={name,mean,error,z,p},
  every head row/.style={output empty row, after row=\\},
  every last row/.style={after row=[3ex]\bottomrule},
  % Set header name
  columns/name/.style={string type,column name={}},
    % Use the ``error'' column to call the \errplot command in a multirow cell in the first row, keep empty for all other rows
  columns/error/.style={
    column name={$\bar{x} \pm$ 95\% CI},
    assign cell content/.code={% use \multirow for Z column:
    \ifnum\pgfplotstablerow=1
    \pgfkeyssetvalue{/pgfplots/table/@cell content}
    {\multirow{\numberofrows}{6.5cm}{\errplot{\dataB}}}%
    \else
    \pgfkeyssetvalue{/pgfplots/table/@cell content}{}%
    \fi
    }
  },
  % Format numbers and titles
  columns/mean/.style={column name=$\bar{x}$, string type, column type={S[table-format=-2.2]}},
  columns/z/.style={column name=$z$, string type, column type={S[table-format=-1.2]}},
  columns/p/.style={column name=$p$, string type, column type={S[table-format=1.2]}},
  ]{\dataB}
\end{table}
\end{document}
7
  • Thanks for help! Hmm...I get an error: `two_tables_with_graph.tex:132: Package pgfkeys Error: I do not know the key '/pgfplots/table/create col/output empty row' and I am going to ignore it. Perhaps you misspelled it. [ ]{\dataB}] – Mikko Jan 27 '14 at 19:21
  • @Largh: Ah, maybe you're using an older version of PGFPlots. output empty row is a new feature that makes it possible to disable the header row without having to set column name={} for every column. It's not required for the overall solution, though. – Jake Jan 27 '14 at 19:40
  • Ok. Thanks. I'll update my LaTeX packages... – Mikko Jan 27 '14 at 20:03
  • 1
    Yes, it was the output empty row command on line 112, which caused the error, in case somebody else gets a similar error later. Solutions: remove the command and the column names for the dataB table or update your TeX. MacTeX-2012 is too old for this stuff =) You'll need to update everything. – Mikko Jan 28 '14 at 6:38
  • I did a little bit more experimentation. This solution has some weird problem with column names. For instance, if I change the column name on row 105 to y, it still works, and ya works too, but ye returns an error: ./two_tables_with_graph.tex:108: !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! [ ]{\dataA}]. So does for example mean. Any idea what is the problem? – Mikko Jan 28 '14 at 9:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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