# row index of first non-zero element in pgfplotstable

I am using the "functions" \findmin and findmax from here quite much to dynamical format and set plots from CSV data I read in.

In the same vein, I want a function \findFirstNonZeroIndex, which returns the integer index of the first element which is non-zero in a specified column. Since all my data are non-negative integers, non-zero is equal to being greater than 0.

Since the indices in pgfplotstable start with 0, how do I add 1 to this number?

From the pgfplotstable manuel, the iflessthan command seems capable of doing what I want:

\pgfplotstablesort[sort key={#2},sort cmp={
iflessthan/.code args={#1#2#3#4}{%
}%
}]{\result}{\datatable}


Some example data:

\begin{filecontents}{table.dat}
x y
1 0
2 0
3 30
4 0
5 50
\end{filecontents}


If possible, I do only want to use the column =y=index[1] and get something like \findFirstNonZeroIndex{\inputtable}{\outputvalue}. In this example, \outputvalue should be 3.

If it is easier, up to now I only use integer values in column y sorted ascending. So there would not be a 0 in row x=4.

I just do not know enough on how to get started. Any help would be appreciated.

# Edit

Steven B. Segletes just answered my question with the help of package readarray.

Out of curiosity, is there a solution using the pgf framework?

Here's how you can do this using PGFPlotstable. I defined a macro that takes three arguments: The macro containing the table that was loaded using \pgfplotstableread, the name of the column, and the macro that contains the output. Note that PGFPlotstable uses zero based indexing, so if the first non-zero element is in the third row, the output will be 2. If no non-zero values are found, the output will be -1.

\documentclass{article}
\usepackage{filecontents}
\usepackage{pgfplotstable}

\begin{filecontents}{table.dat}
x y
1 0
2 0
3 30
4 0
5 50
\end{filecontents}

\newcommand\findFirstNonZeroIndex[3]{
\def#3{-1}
\pgfplotstableforeachcolumnelement{#2}\of{#1}\as\cell{
\ifnum#3=-1
\ifnum\cell>0
\xdef#3{\pgfplotstablerow}
\fi
\fi
}
}

\begin{document}

\findFirstNonZeroIndex{\datatable}{y}{\outputvalue}
\outputvalue

\end{document}

• Thank you. As I understand this approach only works when comparing integers, as I requested (because of \ifnum ?!). How would one modify this solution to compare doubles, i.e. find the first row with double element > 0? Feb 24 '15 at 14:30
• @MarcoBreitig: Do you have large numbers (greater than 16000)?
– Jake
Feb 24 '15 at 14:41
• No, between 100 to 3000 elements per column. Feb 24 '15 at 15:08
• @MarcoBreitig: Sorry, I meant the values of your floats. If they're under 16000 you can simply use \ifdim\cell pt>0pt, but if they're larger than that you'll need to use the fpu library.
– Jake
Feb 24 '15 at 15:14
• In the same region, just counting. The double data is in [0,1], building ratios. Thx, I just tried it and it works. :-) Feb 24 '15 at 15:22

The macro \firstdata{column} will find the first positive entry in the specified column (beginning at row 2, since row 1 is alphabetic). Once found, it will output the value of column 1 from that row, which, in the data structure, is the datapoint number.

Thus, this MWE outputs the result 3.

The readarray package stores the file in one large \def, in this case \mydata. It then creates an array structure, here named thedata, by reading \mydata as a 2 column array of space-separated values. Individual cells of the array may be recalled with \arrayij{thedata}{row}{column} and compared against 0 to detect positiveness.

\documentclass{article}
\begin{filecontents*}{table.dat}
x y
1 0
2 0
3 30
4 0
5 50
\end{filecontents*}
\newcounter{currentrow}
\def\firstdata#1{%
\setcounter{currentrow}{1}%
\whiledo{\value{currentrow}<\thedataROWS}{%
\stepcounter{currentrow}%
\ifnum\arrayij{thedata}{\thecurrentrow}{#1}>0
\arrayij{thedata}{\thecurrentrow}{1}%
\setcounter{currentrow}{\thedataROWS}%
\fi%
}%
}
\begin{document}
\firstdata{2}
\end{document}

• Thx! I see you use the packages readarray and filecontents. Are they related to pgf or on their own? Feb 24 '15 at 12:27
• They are on their own. I wrote the readarray package, but don't know a lick about pgf. Feb 24 '15 at 12:27
• @MarcoBreitig I only use filecontents as a vehicle to create the data to begin with. If the data already exists in a separate file, or is placed inside of a \def within the document through some other means, the filecontents would not be required. Feb 24 '15 at 12:34
• Ah of course. That is the pitfall if you do not give a MWE yourself. Thank you for pointing this out! Feb 24 '15 at 12:48