1

Trying to make a table from a csv file, where i can define the first column manually or by a vector/column.

It works if the only different in the first column is the subscript from 1 to 12 as seen here:

\begin{table}[]
    \centering
  \resizebox{\textwidth}{!}{  
    \begin{tabular}{c?c|c|c|c|c|c|c|c|c|c|c|c}
        \textbf{Mode} & \textbf{1} & \textbf{2} & \textbf{3} & \textbf{4} & \textbf{5} & \textbf{6} & \textbf{7} & \textbf{8} & \textbf{9} & \textbf{10} & \textbf{11} & \textbf{12} \\\PARTYLINE
        %
        \csvreader[column count=12,no head,late after line=\\\hline]{Results/E1_EVx.csv}{1=\aaa, 2=\bbb, 3=\ccc, 4=\ddd, 5=\eee, 6=\fff, 7=\ggg, 8=\hhh, 9=\iii, 10=\jjj, 11=\kkk, 12=\lll}
        {\textbf{DOF$_\thecsvrow$} & \aaa & \bbb & \ccc & \ddd & \eee & \fff & \ggg & \hhh & \iii & \jjj & \kkk & \lll}
    \end{tabular}}
\end{table}

enter image description here

But if i instead would like the first row to be e.g. [DOF A, Dof B, Dof C, Dof D, Dof E, Dof F, Dof G, Dof H, Dof I, Dof J, Dof K, Dof L]

Anyone who know how I can do that, without editting my csv file with data.

I got this csv file generated from matlab with our values

0.19,0.62,1,0.95,0,0,0,0,-0.06,-0.05,-0.03,-0.04
-0.08,-0.18,-0.1,0.18,-0.16,-0.9,-1,0.65,-0.36,-0.93,1,0.59
-0.08,-0.18,-0.1,0.18,0.16,0.9,1,-0.65,-0.36,-0.93,1,0.59
0.52,0.95,0.07,-1,0,0,0,0,0.05,-0.08,0.09,-0.02
-0.08,0.06,0.4,0.06,0.35,1,-0.33,1,0.62,0.78,0.55,1
-0.08,0.06,0.4,0.06,-0.35,-1,0.33,-1,0.62,0.78,0.55,1
0.81,0.17,-0.94,0.73,0,0,0,0,-0.03,0.13,0.07,0.02
-0.06,0.28,-0.11,-0.24,-0.61,-0.2,0.89,0.89,-0.81,0.17,-0.76,1
-0.06,0.28,-0.11,-0.24,0.61,0.2,-0.89,-0.89,-0.81,0.17,-0.76,1
1,-1,0.73,-0.36,0,0,0,0,-0.07,0.01,-0.03,0.04
-0.04,0.26,-0.48,0.45,1,-0.78,0.63,0.38,1,-1,-0.91,0.6
-0.04,0.26,-0.48,0.45,-1,0.78,-0.63,-0.38,1,-1,-0.91,0.6
3
  • Welcome to TeX.SE!
    – Mensch
    Commented Nov 8, 2021 at 12:12
  • Thanks a lot. Hoping for a smart solution for this. :) Commented Nov 8, 2021 at 12:23
  • Without looking into the details of your question, you could potentially find a solution involving the pgfplotstable package. It also has a great manual.
    – Raven
    Commented Nov 8, 2021 at 14:42

3 Answers 3

2

An alternative using knitr, but using booktabs for minimal and elegant rules and siunitx for number format (check that hyphens are displayed as minus signs are not simply hyphens!). Note that R code control dimensions of tablet through optional parameters scale, size and digits (digits=1 maybe is better that leave a tiny font, for instance).

mwe

MWE.Rnw (Rstudio) or MWE.Rtex (Overleaf):

\documentclass[11pt]{article}
\usepackage{booktabs,tabulary,siunitx,array}
\usepackage{lipsum}

\begin{filecontents*}[overwrite]{test.csv}
0.19,0.62,1,0.95,0,0,0,0,-0.06,-0.05,-0.03,-0.04
-0.08,-0.18,-0.1,0.18,-0.16,-0.9,-1,0.65,-0.36,-0.93,1,0.59
-0.08,-0.18,-0.1,0.18,0.16,0.9,1,-0.65,-0.36,-0.93,1,0.59
0.52,0.95,0.07,-1,0,0,0,0,0.05,-0.08,0.09,-0.02
-0.08,0.06,0.4,0.06,0.35,1,-0.33,1,0.62,0.78,0.55,1
-0.08,0.06,0.4,0.06,-0.35,-1,0.33,-1,0.62,0.78,0.55,1
0.81,0.17,-0.94,0.73,0,0,0,0,-0.03,0.13,0.07,0.02
-0.06,0.28,-0.11,-0.24,-0.61,-0.2,0.89,0.89,-0.81,0.17,-0.76,1
-0.06,0.28,-0.11,-0.24,0.61,0.2,-0.89,-0.89,-0.81,0.17,-0.76,1
1,-1,0.73,-0.36,0,0,0,0,-0.07,0.01,-0.03,0.04
-0.04,0.26,-0.48,0.45,1,-0.78,0.63,0.38,1,-1,-0.91,0.6
-0.04,0.26,-0.48,0.45,-1,0.78,-0.63,-0.38,1,-1,-0.91,0.6
\end{filecontents*}

\begin{document}  
\lipsum[1][1-4] % to see the actual margins
\tabcolsep1pt
<<results='asis',echo=F,message=F,warning=F>>=
require(xtable)
bold <- function(x){paste0('{\\bfseries ', x, '}')}
df <- data.frame(Mode=paste("DOF ", LETTERS[1:12], sep="")) # Mode data
df[,2:13] <- read.csv("test.csv",header=F) # read the number of external file
colnames(df) <- c("Mode",1:12) # Names fir columns 
rownames(df) <- df[,1]  # "Mode" as rownames (no header)
df[,1] <- NULL          # "Mode" as rownames (no header)
tdf <- xtable(df, caption="My small table.", align=c("p{5em}",rep("S[table-format = 3.2]",12)), digits=2)
print(tdf,  booktabs=T, size="\\scriptsize",
      include.rownames=T,
      sanitize.rownames.function = bold,
      sanitize.colnames.function = bold, 
      scale=1,
      caption.placement = "top")
@
\end{document}
0

I have never used csvreader but as mentioned in the comments here ist my solution with pgfplotstable:

table

\documentclass{standalone}

\usepackage{pgfplotstable}

\begin{document}
    \pgfplotstabletypeset[
        col sep=comma, fixed,
        %create on use/Mode/.style={create col/set list={1,2,...,12}},
        %create on use/Mode/.style={create col/set list={a,b,...,l}},
        create on use/Mode/.style={create col/set list={A,B,...,L}},
        columns/Mode/.style={ % write as subscript
            string type,
            preproc cell content/.code={
                \pgfkeysgetvalue{/pgfplots/table/@cell content}\oldcontent%
                \edef\temp{\noexpand\pgfkeyssetvalue{/pgfplots/table/@cell content}{DOF$_{\oldcontent}$}}%
                \temp%
            }
        },
        columns={Mode,0,1,2,3,4,5,6,7,8,9,10,11},
        assign column name/.code={ % header bold and fix start of index
            \ifnum\pgfplotstablecol>0
                \pgfkeyssetvalue{/pgfplots/table/column name}{\pgfmathparse{int(#1+1)}\textbf{\pgfmathresult}}%
            \else
                \pgfkeyssetvalue{/pgfplots/table/column name}{\textbf{#1}}%
            \fi
        },
        every column/.style={column type/.add={|}{}},
        every first column/.style={column type/.add={}{|}},
        every last column/.style={column type/.add={}{|}},
        every nth row={1}{before row=\hline},       
        every head row/.style={before row=\hline, after row=\hline\hline},
        every last row/.style={after row=\hline}
    ]{E1_EVx.csv}
\end{document}
0

Let's keep thing simple with csvsimple.

a

Define the new names using a command like \CellValue.

\documentclass[11pt]{article}

\usepackage{csvsimple-l3}   

\usepackage{graphicx}

\begin{filecontents*}[overwrite]{E1EVx.csv}
0.19,0.62,1,0.95,0,0,0,0,-0.06,-0.05,-0.03,-0.04
-0.08,-0.18,-0.1,0.18,-0.16,-0.9,-1,0.65,-0.36,-0.93,1,0.59
-0.08,-0.18,-0.1,0.18,0.16,0.9,1,-0.65,-0.36,-0.93,1,0.59
0.52,0.95,0.07,-1,0,0,0,0,0.05,-0.08,0.09,-0.02
-0.08,0.06,0.4,0.06,0.35,1,-0.33,1,0.62,0.78,0.55,1
-0.08,0.06,0.4,0.06,-0.35,-1,0.33,-1,0.62,0.78,0.55,1
0.81,0.17,-0.94,0.73,0,0,0,0,-0.03,0.13,0.07,0.02
-0.06,0.28,-0.11,-0.24,-0.61,-0.2,0.89,0.89,-0.81,0.17,-0.76,1
-0.06,0.28,-0.11,-0.24,0.61,0.2,-0.89,-0.89,-0.81,0.17,-0.76,1
1,-1,0.73,-0.36,0,0,0,0,-0.07,0.01,-0.03,0.04
-0.04,0.26,-0.48,0.45,1,-0.78,0.63,0.38,1,-1,-0.91,0.6
-0.04,0.26,-0.48,0.45,-1,0.78,-0.63,-0.38,1,-1,-0.91,0.6
\end{filecontents*}
    
\newcommand{\CellValue}{% added <<<<<<<<<<<<<<<<
\ifnum \thecsvrow =1 DOF A \fi
\ifnum \thecsvrow =2 DOF B \fi
\ifnum \thecsvrow =3 DOF C \fi
\ifnum \thecsvrow =4 DOF D \fi
\ifnum \thecsvrow =5 DOF E \fi
\ifnum \thecsvrow =6 DOF F \fi
\ifnum \thecsvrow =7 DOF G \fi
\ifnum \thecsvrow =8 DOF H \fi
\ifnum \thecsvrow =9 DOF I \fi
\ifnum \thecsvrow =10 DOF J \fi
\ifnum \thecsvrow =11 DOF K \fi
\ifnum \thecsvrow =12 DOF L \fi
}
    
\begin{document}        

\begin{table}
    \centering
    \resizebox{\textwidth}{!}{%<<< important
        \begin{tabular}{l|c|c|c|c|c|c|c|c|c|c|c|c}
            \textbf{Mode} & \textbf{1} & \textbf{2} & \textbf{3} & \textbf{4} & \textbf{5} & \textbf{6} & \textbf{7} & \textbf{8} & \textbf{9} & \textbf{10} & \textbf{11} & \textbf{12} \\ 
            \hline
            \csvreader[column count=12,no head,late after line=\\\hline]{E1EVx.csv}{1=\aaa, 2=\bbb, 3=\ccc, 4=\ddd, 5=\eee, 6=\fff, 7=\ggg, 8=\hhh, 9=\iii, 10=\jjj, 11=\kkk, 12=\lll}
            {\textbf{\CellValue} & \aaa & \bbb & \ccc & \ddd & \eee & \fff & \ggg & \hhh & \iii & \jjj & \kkk & \lll}
    \end{tabular}}
\end{table}

\end{document}

Margin note

The way \CellValue is implemented may be easy to understand but it is very inefficient: all 12 \ifnum are executed every time. The execution time grows with the square of the number of entries.

A much better way is to implement a lookup to find the correct value at once. The execution time will increase linearly with the number of entries.

First, the lookup is populated by creating a new command for each entry using \lookupPut{<row number>}{<cell value>}.

The value of the cell is retrieved with \CellValue {<row number>}

If the cell value was not defined for a certain row, the cell will be filled with "?????", as seen in the image.

d

See implement a lookup

\documentclass[11pt]{article}

\usepackage{csvsimple-l3}   

\usepackage{graphicx}

\begin{filecontents*}[overwrite]{E1EVx.csv}
0.19,0.62,1,0.95,0,0,0,0,-0.06,-0.05,-0.03,-0.04
-0.08,-0.18,-0.1,0.18,-0.16,-0.9,-1,0.65,-0.36,-0.93,1,0.59
-0.08,-0.18,-0.1,0.18,0.16,0.9,1,-0.65,-0.36,-0.93,1,0.59
0.52,0.95,0.07,-1,0,0,0,0,0.05,-0.08,0.09,-0.02
-0.08,0.06,0.4,0.06,0.35,1,-0.33,1,0.62,0.78,0.55,1
-0.08,0.06,0.4,0.06,-0.35,-1,0.33,-1,0.62,0.78,0.55,1
0.81,0.17,-0.94,0.73,0,0,0,0,-0.03,0.13,0.07,0.02
-0.06,0.28,-0.11,-0.24,-0.61,-0.2,0.89,0.89,-0.81,0.17,-0.76,1
-0.06,0.28,-0.11,-0.24,0.61,0.2,-0.89,-0.89,-0.81,0.17,-0.76,1
1,-1,0.73,-0.36,0,0,0,0,-0.07,0.01,-0.03,0.04
-0.04,0.26,-0.48,0.45,1,-0.78,0.63,0.38,1,-1,-0.91,0.6
-0.04,0.26,-0.48,0.45,-1,0.78,-0.63,-0.38,1,-1,-0.91,0.6
\end{filecontents*}
    


%% https://tex.stackexchange.com/a/249529/161015
%% A way to implement a lookup is using the hash table of TeX by defining
% a macro \lookup@<key> which expands to <value>:   
\makeatletter
\newcommand{\CellValue}[1]{%
    \@ifundefined{lookup@#1}
    {?????}{\@nameuse{lookup@#1}}%
}
\newcommand{\lookupPut}[2]{%
    \@namedef{lookup@#1}{#2}%
}
\makeatother

        
\begin{document}
        
\lookupPut{1}{DOF A}
\lookupPut{2}{DOF B}
\lookupPut{3}{DOF C}    
\lookupPut{4}{DOF D}
\lookupPut{5}{DOF E}
\lookupPut{6}{DOF F}
\lookupPut{7}{DOF G}
\lookupPut{8}{DOF H}
\lookupPut{9}{DOF I}    
\lookupPut{10}{DOF J}
\lookupPut{11}{DOF K}
%\lookupPut{12}{DOF L}  % deliberately not defined  

\begin{table}
    \centering
    \resizebox{\textwidth}{!}{%<<< important
        \begin{tabular}{l|c|c|c|c|c|c|c|c|c|c|c|c}
            \textbf{Mode} & \textbf{1} & \textbf{2} & \textbf{3} & \textbf{4} & \textbf{5} & \textbf{6} & \textbf{7} & \textbf{8} & \textbf{9} & \textbf{10} & \textbf{11} & \textbf{12} \\ 
            \hline
            \csvreader[column count=12,no head,late after line=\\\hline]{E1EVx.csv}{1=\aaa, 2=\bbb, 3=\ccc, 4=\ddd, 5=\eee, 6=\fff, 7=\ggg, 8=\hhh, 9=\iii, 10=\jjj, 11=\kkk, 12=\lll}
            {\textbf{\CellValue{\thecsvrow}} & \aaa & \bbb & \ccc & \ddd & \eee & \fff & \ggg & \hhh & \iii & \jjj & \kkk & \lll}
    \end{tabular}}
\end{table}
    

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .