pgfplotstable:根據輸入資料變更為多列行

pgfplotstable:根據輸入資料變更為多列行

假設我有大量的資料行,它們的結構很簡單.csv,而這些資料行可以分為不同的資料類型。

在 MWE 中我剛剛添加了兩種類型 ( typA& typB)。

如果該行包含typA,則該表應按原樣列印並顯示在我的結果中。

如果該行包含typB,則該行應該是多列行,其中僅將欄位的內容Description列印在中心。

我怎麼才能用 LaTeX 達成這個目標? :)

微量元素

\documentclass{article}
\usepackage[a4paper, margin=10mm]{geometry}
\usepackage{pgfplotstable}
\usepackage{mwe}
\pgfplotsset{compat=newest}

\begin{filecontents}{data.csv}
Type, Description, X-Pos, Y-Pos
typA, PowerSupply, 3590,  2000
typA, PowerSupply, 3590,  2500
typB, PowerSupply, 4250,  6070
typA, singleSwitch,5700,  6070
\end{filecontents}

\pgfplotstableread[col sep=comma]{data.csv}{\csvdata}
\pgfplotstablegetrowsof{\csvdata}
\pgfmathtruncatemacro\CSVDataRows{\pgfplotsretval-1} 

\begin{document}
\begin{center}
\pgfplotstabletypeset[%
font=\ttfamily,%
col sep=comma,%
columns={Type,Description,X-Pos,Y-Pos},%
columns/Type/.style={%
column name=Type,%
string type%
},%
columns/Description/.style={%
column name=Description,%
string type%
},%
columns/X-Pos/.style={%
column name=X-Pos%
},%
columns/Y-Pos/.style={%
column name=Y-Pos,%
column type/.add={}{|}%
},%
column type/.add={|}{},%
after row={\hline},%
every head row/.style={before row=\hline},
]{\csvdata}%
\end{center}
\end{document}

結果

在此輸入影像描述

預期結果

在此輸入影像描述

編輯

我的想法是添加這樣的內容:

every column/.style={%
    assign cell content/.code={%
        \pgfplotstablegetelem{\pgfplotstablerow}{Type}\of{\csvdata}
        \ifthenelse{\equal{\pgfplotsretval}{typB}}{%
            \ifthenelse{\equal{\pgfplotstablecol}{2}}{%=> Just do this once!
                \pgfkeyssetvalue{/pgfplots/table/@cell content}{\multicolumn{2}{c|}{Content Description}\\\hline}
            }{}
        }{}
    },
},

第二次MWE

\documentclass{standalone}
\usepackage{pgfplotstable}
\usepackage{ifthen}
\pgfplotsset{compat=newest}

\begin{filecontents}{data.csv}
Type, Description, X-Pos, Y-Pos
typA, PowerSupply, 3590,  2000
typA, PowerSupply, 3590,  2500
typB, PowerSupply, 4250,  6070
typA, singleSwitch,5700,  6070
\end{filecontents}

\pgfplotstableread[col sep=comma]{data.csv}{\csvdata}
\pgfplotstablegetrowsof{\csvdata}
\pgfmathtruncatemacro\CSVDataRows{\pgfplotsretval-1} 

\begin{document}
\pgfplotstabletypeset[%
font=\ttfamily,%
col sep=comma,%
columns={Type,Description,X-Pos,Y-Pos},%
columns/Type/.style={%
column name=Type,%
string type%
},%
every column/.style={%
    assign cell content/.code={%
        \pgfplotstablegetelem{\pgfplotstablerow}{Type}\of{\csvdata}
        \ifthenelse{\equal{\pgfplotsretval}{typB}}{%
            \ifthenelse{\equal{\pgfplotstablecol}{2}}{%=> Just do this once!
                \pgfkeyssetvalue{/pgfplots/table/@cell content}{\multicolumn{2}{c|}{Content Description}\\\hline}
            }{}
        }{}
    },
},
columns/Description/.style={%
    column name=Description,%
    string type%
},%
columns/X-Pos/.style={%
    column name=X-Pos%
},%
columns/Y-Pos/.style={%
    column name=Y-Pos,%
    column type/.add={}{|}%
},%
column type/.add={|}{},%
after row={\hline},%
every head row/.style={before row=\hline},
]{\csvdata}%
\end{document}

結果

在此輸入影像描述

但我怎麼才能得到

  1. 從第一列開始的多列
  2. 使用 Y-Pos 訊息抑制第二行
  3. Content Description在這種情況下,用描述的真實內容替換PowerSupply

答案1

您可以接受csvsimple-l3和 的解決方案嗎?tabularray

\documentclass{article}
\usepackage[a4paper, margin=10mm]{geometry}

\usepackage{csvsimple-l3}

\usepackage{tabularray}
\UseTblrLibrary{siunitx}
\sisetup{
  group-digits=integer,
  group-minimum-digits={3},
  group-separator={,}
  }

\begin{filecontents*}{data.csv}
Type, Description, X-Pos, Y-Pos
typA, PowerSupply, 3590,  2000
typA, PowerSupply, 3590,  2500
typB, PowerSupply, 4250,  6070
typA, singleSwitch,5700,  6070
\end{filecontents*}

\begin{document}
\csvreader[no head,
centered tabularray =
{
colspec={cc*2{S[table-format=4]}}, 
columns={font=\ttfamily},
hlines,
vlines,
},
]{data.csv}{}{%
\ifcsvfirstrow{% header
  \csvcoli & \csvcolii
  & {{{\csvcoliii}}}
  & {{{\csvcoliv}}}
    }{% rows
  \IfCsvsimStrEqualTF{\csvcoli}{typB}{% multicolumn
    \SetCell[c=4]{c}\csvcolii&&&}{% other rows
    \csvcoli & \csvcolii
    & \csvcoliii
    & \csvcoliv}
        }
    }
\end{document}

在此輸入影像描述

您也可以使用csvsimple-l3普通的tabular,但有一個技巧,即第五個虛擬列,以避免siunitx最後一列中的列類型出現問題:

\documentclass{article}
\usepackage[a4paper, margin=10mm]{geometry}

\usepackage{csvsimple-l3}
\usepackage{array}
\renewcommand{\arraystretch}{1.3}
\usepackage{siunitx}
\sisetup{
  group-digits=integer,
  group-minimum-digits={3},
  group-separator={,},
    table-number-alignment=center
  }

\begin{filecontents*}{data.csv}
Type, Description, X-Pos, Y-Pos
typA, PowerSupply, 3590,  2000
typA, PowerSupply, 3590,  2500
typB, PowerSupply, 4250,  6070
typA, singleSwitch,5700,  6070
\end{filecontents*}

\begin{document}
\csvreader[
  head to column names,
  before reading = {\begin{center}\ttfamily},
  tabular = {|c|c|S[table-format=4]|S[table-format=4]@{}c|},% the last dummy column is necessary
    % due to csvreader-l3 problems, see documentation, Section 7.4 Tables with Number Formatting
  table head = {\hline Type & Description & {X-Pos} & {Y-Pos}&\\\hline},
  late after line = \\\hline,
  after reading = \end{center}
  ]{data.csv}{}{%
  \IfCsvsimStrEqualTF{\csvcoli}{typB}{% multicolumn
    \multicolumn{5}{|c|}{\csvcolii}
        }{% other rows
    \csvcoli & \csvcolii
    & \csvcoliii
    & \csvcoliv &
        }
  }
\end{document}

在此輸入影像描述

NB = 該巨集\IfCsvsimStrEqualTF是最近才出現的。如果您的發行版不是最新的,請改用\ifcsvstrcmp。在上面的兩個範例中,舊宏的結果沒有改變。

答案2

這是針對 OpTeX 用戶的解決方案:

\createfile {data.csv}
Type, Description, X-Pos, Y-Pos
typA, PowerSupply, 3590,  2000
typA, PowerSupply, 3590,  2500
typB, PowerSupply, 4250,  6070
typA, singleSwitch,5700,  6070
\endfile

\def\p #1,#2,#3,#4#5 {%
   \ifx^#1^\else
      \isequal{typB}{#1}
      \iftrue
         \mspan4[|c|]{#2} \crl
      \else
         #1 & #2 & #3 & #4#5 \crl
      \fi
      \ea\p
   \fi
}

{\everyeof{,,,{} }
\table{|c|c|c|c|}{\crl
   \ea\p\input data.csv
}}

\bye

相關內容