# Getting specific row/column values from a csv file to use in text, figures or table cells

I am trying to do the following:

1. read a csv (or other similar format) external file with numerical and string data into an object;

2. reference/get an specific value from such object to use into an specific cell of a table or in a figure.

That means, I do not want to convert a csv file or such into a table. I do not want to use packages to build a table.

So, for instance, suppose that I have the following code to generate a very simple table:

\documentclass[]{article}

\begin{document}

\begin{table}[]
\centering
\caption{My example}
\begin{tabular}{lllll}
1  & 2  & 3  & 4  & 5 \\
6  & 7  & 8  & xyz  & 9 \\
10 & 11 & 12 & 13 & 14
\end{tabular}
\end{table}

\end{document}


Where it is written "xyz", I want to actually write a command that references/gets the value of a specific row/column of a csv or similar file. Is there a way to accomplish such a thing?

This uses lua function call to read the specific field in the CVS file. For example, given this CVS file in the directory

123,Poty city,Poti,red,-295731.42857144,617222.85714285
124,Lanchhuti city,Poti,red,-299217.14285715,647851.42857142
125,Ozurgeti city,Poti,red,-317217.14285715,648422.85714285
126,Samtredia city,Poti,red,-287502.85714287,672022.85714285


Then to insert, say the field located at row 2 and column 5, which is -299217.14285715, and the field at row 1 and column 3, which is Poty city in the Latex table, then the code is

\begin{tabular}{|l|l|l|l|l|}\hline
1  & \getField{1}{2}   & 3  & 4                & 5 \\\hline
6  & 7                 & 8  & \getField{2}{5}  & 9  \\\hline
10 & 11                & 12 & 13               & 14 \\\hline
\end{tabular}


Which generates the table:

The full code is below. I googled lua code to parse CVS files, there are few on the net, I found one that worked and used it. There does not seem to be a build in API in lua itself for this. The CVS file is read automatically. The cvs file name is hardcoded in the code below. The latex file needs to be compiled with lualatex not pdflatex

\documentclass[]{article}
\usepackage{luacode}

local function split(str, sep)
fields={}
local matchfunc = string.gmatch(str, "([^"..sep.."]+)")
if not matchfunc then return {str} end
for str in matchfunc do
table.insert(fields, str)
end
return fields
end

tonum = tonum or true
sep = sep or ','
local csvFile = {}
local file = assert(io.open(path, "r"))
for line in file:lines() do
fields = split(line, sep)
if tonum then -- convert numeric fields to numbers
for i=1,#fields do
fields[i] = tonumber(fields[i]) or fields[i]
end
end
table.insert(csvFile, fields)
end
file:close()
return csvFile
end

local m = read('./c.cvs') -- read file csv file to local matrix m

function getField(row,col) -- API to latex command below
tex.print(m[row][col])
end

\end{luacode*}
\newcommand\getField[2]{\directlua{getField(#1,#2) }}%

\begin{document}

\begin{table}[]
\centering
\caption{My example}
\begin{tabular}{|l|l|l|l|l|}\hline
1  & \getField{1}{2}   & 3  & 4                & 5 \\\hline
6  & 7                 & 8  & \getField{2}{5}  & 9  \\\hline
10 & 11                & 12 & 13               & 14 \\\hline
\end{tabular}
\end{table}

\end{document}


Update

I figured why stop at just reading field? Why not add a Latex command to load the whole CVS file and convert it to a Latex table? This will be much more useful also. So here is a new implementation that loads a CVS file and makes a Latex table, all automatically. This will be useful for making reports and such.

The Latex command is called getCVS{"fileName"} and used as follows

\begin{table}[]
\centering
\caption{My CVS file in a Latex table}
\getCVS{"c.cvs"}
\end{table}


Using the above CVS file, the table generated is

The full code is below

\documentclass[]{article}
\usepackage{luacode}
local function split(str, sep)
fields={}
local matchfunc = string.gmatch(str, "([^"..sep.."]+)")
if not matchfunc then return {str} end
for str in matchfunc do
table.insert(fields, str)
end
return fields
end

tonum = tonum or true
sep = sep or ','
local csvFile = {}
local file = assert(io.open(path, "r"))
for line in file:lines() do
fields = split(line, sep)
if tonum then -- convert numeric fields to numbers
for i=1,#fields do
fields[i] = tonumber(fields[i]) or fields[i]
end
end
table.insert(csvFile, fields)
end
file:close()
return csvFile
end
function getCVS(fileName)
local nRow = #m
local nCol = #m[1]
tex.sprint("\\begin{tabular}{")
for j=1,nCol do
tex.sprint("|l")
end
tex.print("|}\\hline")

for i = 1,nRow do
for j = 1,nCol do
tex.sprint(m[i][j])
if j<nCol then tex.sprint("&") end
end
tex.print("\\\\ \\hline")
end
tex.print("\\end{tabular}")
end

\end{luacode*}
\newcommand\getCVS[1]{\directlua{getCVS(#1) }}%

\begin{document}
\begin{table}[]
\centering
\caption{My CVS file in a Latex table}
\getCVS{"c.cvs"}
\end{table}
\end{document}

• Dear Nasser, thank you very much for your detailed response, that's great. I didn't know how to set that up with lua. In fact, I prefer a solution that does not make me move from pdflatex, so I will wait a bit. But in the meanwhile, I will give your suggestion a good try. – MAnd Jul 20 '15 at 2:48