使用 pgfplotstable 创建列联表

使用 pgfplotstable 创建列联表

我正在尝试创建一种pgfplotstable显示列联表的通用样式(下面的示例取自维基百科) 但我在计算每行和每列的总数并将它们动态添加到表中时遇到了麻烦。

我知道对行进行总计将涉及创建一列并使用\pgfmathaccuma,而总计行应该通过来完成,\pgfplotstablevertcat但即使反复阅读文档,细节似乎仍超出了我的理解范围。

该解决方案应该适用于具有不同列/行数和不同标签的不同表(尽管总计的列和行都可以称为总计,但为了清楚起见,这里使用不同的名称)。

注意:我在下面提供了所需输出的手工格式化的表格以及我迄今为止的努力(使用我想要使用的实际表格格式)。

\documentclass[11pt,a4paper,oneside]{report}
\usepackage{booktabs}
\usepackage{pgfplots}
\usepackage{pgfplotstable}

\begin{document}

\section*{Desired output}
\pgfplotstabletypeset[
  every head row/.style={%
    before row={\toprule 
        & \multicolumn{2}{c}{Handedness}\\            \cmidrule{2-3}},
    after row=\midrule},
  every last row/.style={after row=\bottomrule},
  columns/Gender/.style={string type},
]{
    Gender       Right-handed Left-handed {Total by Gender}
    Male                   43           9               52
    Female                 44           4               48
    {Total by Handedness}  87          13              100
}

\section*{Current efforts}

\pgfplotstableread{
    Gender Right-handed Left-handed
    Male             43           9
    Female           44           4
}\chisquaredata

\pgfplotstabletypeset[
% Does not total up correctly
  create on use/{Total by Gender}/.style={
    create col/expr={\pgfmathaccuma + \thisrow{\pgfplotstablecolname}}},
  every head row/.style={%
    before row={\toprule 
        & \multicolumn{2}{c}{Handedness}\\
        \cmidrule{2-3}},
    after row=\midrule},
  every last row/.style={after row=\bottomrule},
  columns/Gender/.style={string type},
  columns={Gender, Right-handed, Left-handed, {Total by Gender}},
]\chisquaredata

\end{document}

答案1

使用pgfplotstable,向表中添加列比添加行要容易得多,因此我建议先计算行总和,然后转置表,然后计算列总和(现在是行,因此我们可以重复第一个操作)。

这是一个宏\createcontingencytable{<table name>}{<first column name>}{<name for row sums>}{<name for column sums>},它采用一个表和必要的名称,并输出一个\contingencytable包含行和列总和的表的宏。

举个例子,你会说

\createcontingencytable{\chisquaredata}{Gender}{Total by Gender}{Total by Handedness}

\pgfplotstabletypeset[
  every head row/.style={%
    before row={\toprule 
        & \multicolumn{2}{c}{Handedness}\\            \cmidrule{2-3}},
    after row=\midrule},
  every last row/.style={after row=\bottomrule},
  columns/Gender/.style={string type},
  columns={Gender, Right-handed, Left-handed, {Total by Gender}},
]\contingencytable

要得到


它也适用于具有两列和两行以上的表格:

\pgfplotstableread{
    Gender Right-handed Left-handed Ambidextrous
    Male             43           9           10
    Female           44           4            5
    Other            20           3            3
}\chisquaredata

\createcontingencytable{\chisquaredata}{Gender}{Total by Gender}{Total by Handedness}


以下是完整代码

\documentclass[11pt,a4paper,oneside]{report}
\usepackage{booktabs}
\usepackage{pgfplots}
\usepackage{pgfplotstable}

\newcommand{\createcontingencytable}[4]{ %
% #1=table name
% #2=first column name
% #3=new row sum name
% #4=new column sum name
\pgfplotstablecreatecol[
    create col/assign/.code={% In each row ... 
        \def\rowsum{0}
        \pgfmathtruncatemacro\maxcolindex{\pgfplotstablecols-1}
        % ... loop over all columns, summing up the elements
        \pgfplotsforeachungrouped \col in {1,...,\maxcolindex}{
            \pgfmathsetmacro\rowsum{\rowsum+\thisrowno{\col}}
        }
        \pgfkeyslet{/pgfplots/table/create col/next content}\rowsum
    }
]{#3}{#1}%
%
% Transpose the table, so we can repeat the summation step for the columns
\pgfplotstabletranspose[colnames from={#2},input colnames to={#2}]{\intermediatetable}{#1}
%
% Sums for each column
\pgfplotstablecreatecol[
    create col/assign/.code={%
        \def\colsum{0}
        \pgfmathtruncatemacro\maxcolindex{\pgfplotstablecols-1}
        \pgfplotsforeachungrouped \col in {1,...,\maxcolindex}{
            \pgfmathsetmacro\colsum{\colsum+\thisrowno{\col}}
        }
        \pgfkeyslet{/pgfplots/table/create col/next content}\colsum
    }
]{#4}\intermediatetable
%
% Transpose back to the original form
\pgfplotstabletranspose[colnames from=#2, input colnames to=#2]{\contingencytable}{\intermediatetable}
}
%

\begin{document}

\pgfplotstableread{
    Gender Right-handed Left-handed Ambidextrous
    Male             43           9           10
    Female           44           4            5
    Other            20           3            3
}\chisquaredata

\createcontingencytable{\chisquaredata}{Gender}{Total by Gender}{Total by Handedness}

\pgfplotstabletypeset[
  every head row/.style={%
    before row={\toprule 
        & \multicolumn{3}{c}{Handedness}\\            \cmidrule{2-4}},
    after row=\midrule},
  every last row/.style={after row=\bottomrule},
  columns/Gender/.style={string type},
  columns={Gender, Right-handed, Left-handed, Ambidextrous, {Total by Gender}},
]\contingencytable


\end{document}

相关内容