T-F-S / csvsimple

A LaTeX package for lightweight CSV file processing.
http://www.ctan.org/pkg/csvsimple
LaTeX Project Public License v1.3c
24 stars 5 forks source link

\csvlinetotablerow only works with more than 9 columns and reads wrong data #10

Closed NicoJG closed 3 years ago

NicoJG commented 3 years ago

I'm trying to read in multiple matrices from csv files.
I got it working with \csvreader and \csvlinetotablerow but it does not really work correctly.

I discovered two bugs that probably are related:

l.21 ... line=\]{build/A.csv}{}{\csvlinetotablerow}

- If I read in another csv file with less columns than the file before the remaining columns are filled with the previous data

Minimal Example:

\documentclass{article}

\usepackage{amsmath} \usepackage{csvsimple}

\begin{filecontents}{A.csv} 0,1,2,3,4,5,6,7,8,9 0,1,2,3,4,5,6,7,8,9 \end{filecontents}

\begin{filecontents}{B.csv} 3,4 5,6
\end{filecontents
}

\begin{document}

\begin{equation} A = \begin{pmatrix} \csvreader[no head,late after line=\]{build/A.csv}{}{\csvlinetotablerow} \end{pmatrix} \end{equation} \begin{equation} B = \begin{pmatrix} \csvreader[no head,late after line=\]{build/B.csv}{}{\csvlinetotablerow} \end{pmatrix} \end{equation}

\end{document}


![Screenshot 2021-04-26 152232](https://user-images.githubusercontent.com/55792255/116089553-46a48800-a6a3-11eb-959e-2d00c4286b12.png)
T-F-S commented 3 years ago

\csvlinetotablerow needs to know the number of columns inside the csv file. This number can be given

If neither is given, \csvlinetotablerow is not well-defined.

The first option is something like the following:

\documentclass{article}

\usepackage{amsmath}
\usepackage{csvsimple}

\begin{filecontents*}{A.csv}
a,b,c,d,e,f,g,h,i,j
0,1,2,3,4,5,6,7,8,9
9,8,7,6,5,4,3,2,1,0
\end{filecontents*}

\begin{filecontents*}{B.csv}
a,b
3,4
5,6
\end{filecontents*}

\begin{document}

\begin{equation}
    A =
    \begin{pmatrix}
        \csvreader[late after line=\\]{A.csv}{}{\csvlinetotablerow}
    \end{pmatrix}
\end{equation}
\begin{equation}
    B =
    \begin{pmatrix}
        \csvreader[late after line=\\]{B.csv}{}{\csvlinetotablerow}
    \end{pmatrix}
\end{equation}

\end{document}

Alternatively, the second options uses column count:

\documentclass{article}

\usepackage{amsmath}
\usepackage{csvsimple}

\begin{filecontents*}{A.csv}
0,1,2,3,4,5,6,7,8,9
9,8,7,6,5,4,3,2,1,0
\end{filecontents*}

\begin{filecontents*}{B.csv}
3,4
5,6
\end{filecontents*}

\begin{document}

\begin{equation}
    A =
    \begin{pmatrix}
        \csvreader[no head,column count=10,late after line=\\]{A.csv}{}{\csvlinetotablerow}
    \end{pmatrix}
\end{equation}
\begin{equation}
    B =
    \begin{pmatrix}
        \csvreader[no head,column count=2,late after line=\\]{B.csv}{}{\csvlinetotablerow}
    \end{pmatrix}
\end{equation}

\end{document}
NicoJG commented 3 years ago

Thank you very much! Now it works very well. Maybe this information could be added to the documentation? I also found it quite hard to find out how to just read in a csv file in this way without using a table. Maybe you could add a similar code example to the documentation?

NicoJG commented 3 years ago

I have another question and I don't know where else to ask.

Is it possible to combine csvsimple with amsmath and siunitx to format matrices nicely? I tried the following code, but I got the error:

! Extra }, or forgotten $.
<recently read> }

l.29 ...er[no head,column count=2,late after line=\\
                                                  ]{B.csv}{}{\csvlinet...
\documentclass{article}

\usepackage{amsmath}
\usepackage{csvsimple}
\usepackage{siunitx}

\begin{filecontents*}{A.csv}
0,1,2,3,4,5,6,7,8,9
0,1,2,3,4,5,6,7,8,9
\end{filecontents*}

\begin{filecontents*}{B.csv}
3,4
5,6    
\end{filecontents*}

\begin{document}

\begin{equation}
    A = 
    \begin{pmatrix}
        \csvreader[no head,column count=10,late after line=\\]{A.csv}{}{\csvlinetotablerow}
    \end{pmatrix}
\end{equation}
\begin{equation}
    B = 
    \begin{pmatrix}
        \begin{tabular}{S S}
            \csvreader[no head,column count=2,late after line=\\]{B.csv}{}{\csvlinetotablerow}
        \end{tabular}
    \end{pmatrix}
\end{equation}

\end{document}
T-F-S commented 3 years ago

I have another question and I don't know where else to ask.

A good place to ask TeX-related questions is https://tex.stackexchange.com/

To your new question: Yes, siunitx can be used to format data read with csvsimple.

\csvlinetotablerow is unsuitable to be parsed by siunitx, but you can use explicit entries like \csvcoli & \csvcolii. There is a caveat for the first column which can be circumvented by adding an invisible dummy column with c@{}, see pages 36 and 37 of the documentation.

\documentclass{article}

\usepackage{amsmath}
\usepackage{csvsimple}
\usepackage{siunitx}

\begin{filecontents*}{A.csv}
0,1,2,3,4,5,6,7,8,9
9,8,7,6,5,4,3,2,1,0
\end{filecontents*}

\begin{filecontents*}{B.csv}
3,4
5,6
\end{filecontents*}

\begin{document}

\begin{equation}
    A =
    \begin{pmatrix}
        \csvreader[no head,column count=10,late after line=\\]{A.csv}{}{\csvlinetotablerow}
    \end{pmatrix}
\end{equation}
\begin{equation}
    B =
    \left(
        \begin{tabular}{c@{}S S}
            \csvreader[no head,column count=2,late after line=\\]{B.csv}{}{& \csvcoli & \csvcolii \show\csvlinetotablerow  }
        \end{tabular}
    \right)
\end{equation}

\end{document}