如何在 pgfplotstable 中为每一列单独设置列类型?

如何在 pgfplotstable 中为每一列单独设置列类型?

对于我正在开展的项目,我想编写一个包装器宏\fancyTable,它在后台进行通信pgfplotstable。用户应该能够将列对齐指定为逗号分隔的列表,并指定包含表数据的文件的路径。额外的复杂之处在于数据通常是任意字符串;它可以是时间戳、句子的一部分或数字。在当前测试阶段,包装器宏如下所示:

\fancyTable[r,c,c,l]{FILEPATH}

当前的设计要求是它必须适用于任意数量的列(因此无法针对特定情况进行硬编码)。但是,我为程序分配所做的所有尝试column style均未奏效(甚至更糟的是,每次编译都会导致不同的故障)。

由于我已经尝试了很多可能性,我决定给出一个完整的概述。我剩下的未解决的问题在最后部分问题。因此请随意滚动到末尾。

初始点

目前,我设法对表进行硬编码。

\documentclass{scrreprt} % standalone or minimal do not work well with longtable

\usepackage{pgfplotstable}
\usepackage{longtable}
\usepackage{colortbl}
\usepackage{booktabs}

\begin{document}
    \begin{filecontents}{pgfplotstable_proc-column-style_example.csv}
        date, time, time zone, event
        2019/01/01, 00:00, CET, server installation finished
        2019/01/01, 00:05, CET, server successfully booted
        2019/01/01, 00:06, CET, starting xyz daemon
        2019/01/01, 00:10, CET, admin login
        2019/12/31, 23:58, CET, sudo reboot
        2019/12/31, 23:59, CET, server reboot
    \end{filecontents}

    \pgfplotstabletypeset[
        begin table=\begin{longtable},%
        end table=\end{longtable},%
        header=false,% no specific header data
        col sep=comma,%
        every head row/.style={% 
            output empty row,% prevent printing of column numbers
        },%
        every odd row/.style={before row={\rowcolor[gray]{0.9}}},% highlighting of every second data row
        every first row/.append style={after row={\midrule}},% horizontal line after header
        string type,% necessary for correct processing of table content
        columns/0/.style={column type=r},%
        columns/3/.style={column type=l},%
        % modified from: https://tex.stackexchange.com/questions/130835/pgfplotstable-one-row-in-bold
        postproc cell content/.append code={% setting first row bold
            \count0=\pgfplotstablerow %
            \advance\count0 by1 %
            \ifnum\count0=1 %
            \pgfkeysalso{@cell content=\textbf{#1}}%
            \fi %
        },
    ]{pgfplotstable_proc-column-style_example.csv}
\end{document}

编译返回下表: 在此处输入图片描述

但是,列对齐是固定的:

columns/0/.style={column type=r},%
columns/3/.style={column type=l},%

如果输入数据发生变化,就会导致问题。

尝试 1:pgfplotstable

我的第一个想法是使用 已经提供的宏pgfplotstable,但我只能用 打印与列相关的内容\pgfplotstableforeachcolumn。接下来,我尝试用 创建一个 for 循环\pgfplotsforeachungrouped,但也失败了。就我对pgf和的有限理解而言pgfplotstable,它要么不起作用,因为我无法正确访问表数据,要么宏不是为执行我试图要求它执行的操作而设计的。

尝试 2:\foreach使用\protected@xappto

我的另一个想法是创建一个包含辅助宏中的对齐信息的字符串\columnAlign,并将宏的内容插入到中。对于原型设计,我使用了与\pgfplotstabletypeset[\columnAlign]{FILENAME}相结合的 hack 方法,过去我曾使用这种方法成功创建了表格内容。当然,这行不通;所以不会编译...\foreach\protected@xapptoMWE

\documentclass{minimal}

\usepackage{pgfplotstable}
\usepackage{etoolbox}

\begin{document}
    \begin{filecontents}{pgfplotstable_proc-column-style_example.csv}
        date,time,time zone, event
        2019/01/01, 00:00, CET, server installation finished
        2019/01/01, 00:05, CET, server successfully booted
        2019/01/01, 00:06, CET, starting xyz daemon
        2019/01/01, 00:10, CET, admin login
        2019/12/31, 23:58, CET, sudo reboot
        2019/12/31, 23:59, CET, server reboot
    \end{filecontents}
    
    \pgfplotstableread[header=false,col sep=comma]{pgfplotstable_proc-column-style_example.csv}\loadedtable

    \def\columnAlign{}% define empty helper macro
    \makeatletter
    \foreach \col in {0,1} {% iterate over all columns in \loadedtable
        \protected@xappto\columnAlign{% append column style definition
            columns/\col/.style=\{column type=l\}, 
        }%
    }%
    \makeatother

    \pgfplotstabletypeset[
        every head row/.style={% 
            output empty row,%
        },%
        string type,%
        \columnAlign
    ]\loadedtable
\end{document}

转义字符(如 )存在许多问题, = { },我无法修复。我尝试了\csname ... \endcsname\expandafter等。

尝试 3:(\input{}不要尝试!)

从一开始,我就确信这一定会破裂pgfplotstable;但如果你不尝试,你就无法确定……

我的想法是,我可能可以加载一个外部生成的 tex 文件,该文件pgfplotstable能够加载而不会\csname出现扩展问题。或者,这可能是一种通过 生成管道的方法\input{|"PIPE CONTENT"}

和预期的一样,调用编译\pgfplotstable[\input{FILE1}]{FILE2}不正确。编译冻结/循环,甚至没有生成错误消息。

尝试 4:自定义列样式和./list

尝试 4 与尝试 2 非常相似。但是,它试图利用pgfplotstable可以在输出表域中定义自定义列样式的功能,并可以对其进行迭代。

\pgfplotstableset{%
    left column/.style={%
        /pgfplots/table/display columns/#1/.style={column type=l}%
    },%
    center column/.style={%
        /pgfplots/table/display columns/#1/.style={column type=c}%
    },%
    right column/.style={%
        /pgfplots/table/display columns/#1/.style={column type=r}%
    },%
}%

如果调用样式,例如left column/.list={LIST},则样式将应用于中提供的所有列索引LIST

样式也接受宏作为输入。这样就可以使用 生成多个“宏数组” \protected@xappto,其中包含应应用样式的列的索引。如果没有列应应用某种样式,则相应的“样式宏数组”将为空。

作为原型,我手动创建了宏。

\def\cCenter{0,1,2}
\def\cLeft{3}
\def\cRight{}

\pgfplotstabletypeset[
    left column/.list={\cLeft}, %
    center column/.list={\cCenter}, %
    right column/.list={\cRight}, %
]{FILE}

只要“宏数组”不为空,它就会编译。如果“数组”为空,则编译停止。使用 if-case 仅包含应应用的列样式也不起作用。这使得无法从程序上影响列对齐。

问题:

  1. 我是否错过了一个pgfplotstable可以让我做我想做的事情的宏?
  2. 有没有其他语法方法expl3
  3. 或者,在最坏的情况下,是否根本无法pgfplotstable实现我的目标?如果是这样,是否有其他方法可以从文件中解析表格(例如使用datatool),从而提供类似的功能pgfplotstable(尤其是preproc cell contentpostproc cell content将来我的项目将需要它)?

答案1

另一种解决方案是catchfiletabularray基于我的包回答另一个问题:

\documentclass{scrreprt}

%% % used to make page size smaller and therewith facilitate page break testing
%\usepackage[
%  paperheight=7.5cm, paperwidth=13cm,
%  left=0.5cm, right=0.5cm, top=0.25cm,
%  bottom=0.25cm, includeheadfoot
%]{geometry}

\usepackage{xcolor}
\usepackage{catchfile}
\usepackage{tabularray}

\ExplSyntaxOn
\group_begin:
  \catcode`\^^M=\active %
  \cs_gset_protected:Npn \NormalizeData #1 {%
    \regex_replace_once:nnN { \s * \r ? $ } {} #1
    \tl_greplace_all:Nnn #1 {^^M} {\\}%
    \tl_greplace_all:Nnn #1 {,} {&}%
  }%
\group_end:
\ExplSyntaxOff

\newcommand{\fancyTable}[2][]{
  \CatchFileDef{\mydata}{#2}{\catcode`\^^M=\active}
  \NormalizeData{\mydata}
  \begin{longtblr}[
    expand = \mydata,
    caption = {The Caption of the Table},
  ]{
    colspec = {#1},
    hline{1,Z} = {0.08em},
    hline{2} = {0.05em},
    row{even} = {gray9},
    row{1} = {font=\bfseries},
    rowhead = 1,
  }
    \mydata
  \end{longtblr}
}

\begin{document}

\begin{filecontents*}{628719.csv}
    date, time, time zone, event
    2019/01/01, 00:00, CET, server installation finished
    2019/01/01, 00:05, CET, server successfully booted
    2019/01/01, 00:06, CET, starting xyz daemon
    2019/01/01, 00:10, CET, admin login
    2019/12/31, 23:58, CET, sudo reboot
    2019/12/31, 23:59, CET, server reboot
\end{filecontents*}

%\fancyTable[r]{628719.csv}   % specify only the first column

\fancyTable[rc]{628719.csv}   % specify only the first two columns

%\fancyTable[rcc]{628719.csv} % specify only the first three columns

\fancyTable[rccl]{628719.csv} % specify all of the four columns

\end{document}

在此处输入图片描述

相关内容