]> Creatis software - CreaPhase.git/blob - octave_packages/dataframe-0.9.1/@dataframe/private/df_name2idx.m
Add a useful package (from Source forge) for octave
[CreaPhase.git] / octave_packages / dataframe-0.9.1 / @dataframe / private / df_name2idx.m
1 function [idx, nelem, subs, mask] = df_name2idx(names, subs, count, dimname, missingOK=false);
2
3   %# This is a helper routine to translate rownames or columnames into
4   %# real index. Input: names, a char array, and subs, a cell array as
5   %# produced by subsref and similar. This routine can also detect
6   %# ranges, two values separated by ':'. On output, subs is
7   %# 'sanitised' from names, and is either a vector, either a single ':'
8
9   %% Copyright (C) 2009-2012 Pascal Dupuis <Pascal.Dupuis@uclouvain.be>
10   %%
11   %% This file is part of Octave.
12   %%
13   %% Octave is free software; you can redistribute it and/or
14   %% modify it under the terms of the GNU General Public
15   %% License as published by the Free Software Foundation;
16   %% either version 2, or (at your option) any later version.
17   %%
18   %% Octave is distributed in the hope that it will be useful,
19   %% but WITHOUT ANY WARRANTY; without even the implied
20   %% warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
21   %% PURPOSE.  See the GNU General Public License for more
22   %% details.
23   %%
24   %% You should have received a copy of the GNU General Public
25   %% License along with Octave; see the file COPYING.  If not,
26   %% write to the Free Software Foundation, 51 Franklin Street -
27   %% Fifth Floor, Boston, MA 02110-1301, USA.
28   
29   %#
30   %# $Id: df_name2idx.m 9585 2012-02-05 15:32:46Z cdemills $
31   %#
32
33   if (isempty (subs))
34     %# not caring about rownames ? Avoid generating an error.
35     idx = []; nelem = 0; return
36   endif
37
38   if (isa (subs, 'char')),
39     orig_name = subs;
40     if (1 == size (subs, 1))
41       if (strcmp(subs, ':')) %# range operator
42         idx = 1:count; nelem = count;
43         return
44       endif
45     endif
46     subs = cellstr (subs);
47   else
48     if (~isvector(subs))
49       %# yes/no ?
50       %# error("Trying to access column as a matrix");
51     endif
52     switch (class (subs))
53       case {"cell"}
54         orig_name = char (subs);
55       case {"dataframe"}
56         orig_name = "elements indexed by a dataframe";
57       otherwise
58         orig_name = num2str (subs);
59     endswitch
60   endif
61
62   if (isa (subs, 'cell'))
63     subs = subs(:); idx = []; mask = logical (zeros (size (subs, 1), 1));
64     %# translate list of variables to list of indices
65     for indi = (1:size(subs, 1))
66       %# regexp doesn't like empty patterns
67       if (isempty (subs{indi})) continue; endif
68       %# convert  from standard pattern to regexp pattern
69       subs{indi} = regexprep (subs{indi}, '([^\.\\])(\*|\?)', "$1.$2");
70       %# quote repetition ops at begining of line, otherwise the regexp
71       %# will stall forever/fail
72       subs{indi} = regexprep (subs{indi}, \
73                               '^([\*\+\?\{\}\|])', "\\$1");
74       %# detect | followed by EOL 
75       subs{indi} = regexprep (subs{indi}, '([^\\])\|$', "$1\\|");
76       if (0 == index (subs{indi}, ':'))
77         for indj = (1:min (length (names), count)) %# sanity check
78           if (~isempty (regexp (names{indj}, subs{indi})))
79             idx = [idx indj]; mask(indi) = true;
80           endif
81         endfor
82       else
83         dummy = strsplit (subs{indi}, ':');
84         ind_start = 1;
85         if (!isempty (dummy{1}))
86           ind_start = sscanf (dummy{1}, "%d");
87           if (isempty (ind_start))
88             ind_start = 1;
89             for indj = (1:min(length (names), count)) %# sanity check
90               if (~isempty (regexp (names{indj}, subs{indi}))),
91                 ind_start = indj; break; %# stop at the first match
92               endif
93             endfor
94           endif
95         endif
96         
97         if (isempty (dummy{2}) || strcmp (dummy{2}, 'end'))
98           ind_stop = count;
99         else
100           ind_stop = sscanf(dummy{2}, "%d");
101           if (isempty (ind_stop))
102             ind_stop = 1;
103             for indj = (min (length (names), count):-1:1) %# sanity check
104               if (~isempty (regexp (names{indj}, subs{indi})))
105                 ind_stop = indj; break; %# stop at the last match
106               endif
107             endfor
108           endif
109         endif
110         idx = [idx ind_start:ind_stop];
111       endif
112     endfor
113     if (isempty (idx) && ~missingOK)
114       dummy = sprintf ("Unknown %s name while searching for %s", ...
115                        dimname, orig_name);
116       error (dummy);
117     endif
118   elseif (isa (subs, 'logical'))
119     idx = 1:length (subs(:)); idx = reshape (idx, size (subs));
120     idx(~subs) = []; mask = subs;
121   elseif (isa (subs, 'dataframe'))
122     idx = subsindex (subs, 1);
123   else
124     idx = subs;
125   endif
126
127   subs = idx;
128   nelem = length (idx);
129   
130 endfunction