]> Creatis software - CreaPhase.git/blob - octave_packages/dataframe-0.9.1/@dataframe/subsasgn.m
Add a useful package (from Source forge) for octave
[CreaPhase.git] / octave_packages / dataframe-0.9.1 / @dataframe / subsasgn.m
1 function df = subasgn(df, S, RHS)
2   %# function df = subasgn(df, S, RHS)
3   %# This is the assignement operator for a dataframe object, taking
4   %# care of all the housekeeping of meta-info.
5
6   %% Copyright (C) 2009-2012 Pascal Dupuis <Pascal.Dupuis@uclouvain.be>
7   %%
8   %% This file is part of Octave.
9   %%
10   %% Octave is free software; you can redistribute it and/or
11   %% modify it under the terms of the GNU General Public
12   %% License as published by the Free Software Foundation;
13   %% either version 2, or (at your option) any later version.
14   %%
15   %% Octave is distributed in the hope that it will be useful,
16   %% but WITHOUT ANY WARRANTY; without even the implied
17   %% warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
18   %% PURPOSE.  See the GNU General Public License for more
19   %% details.
20   %%
21   %% You should have received a copy of the GNU General Public
22   %% License along with Octave; see the file COPYING.  If not,
23   %% write to the Free Software Foundation, 51 Franklin Street -
24   %% Fifth Floor, Boston, MA 02110-1301, USA.
25   
26   %#
27   %# $Id: subsasgn.m 9585 2012-02-05 15:32:46Z cdemills $
28   %#
29
30   if (isnull (df))
31     error ('dataframe subsasgn: first argument may not be empty');
32   endif
33   
34   switch (S(1).type)
35     case '{}'
36       error ('Invalid dataframe as cell assignement');
37     case '.'
38       %# translate the external to internal name
39       switch (S(1).subs)
40         case "rownames"
41           if (~isnull (RHS) && isempty (df._name{1}))
42             df._name{1}(1:df._cnt(1), 1) = {''};
43             df._over{1}(1, 1:df._cnt(1)) = true;
44           endif
45           [df._name{1}, df._over{1}] = df_strset \
46               (df._name{1}, df._over{1}, S(2:end), RHS);
47           return
48
49         case "rowidx"
50           if (1 == length(S))
51             df._ridx = RHS;
52           else
53             df._ridx = feval (@subsasgn, df._ridx, S(2:end), RHS);
54           endif
55           return
56           
57         case "colnames"
58           if (isnull(RHS)) error ("Colnames can't be nulled"); endif
59           [df._name{2}, df._over{2}] = df_strset \
60               (df._name{2}, df._over{2}, S(2:end), RHS, '_');
61           df._name{2} = genvarname (df._name{2});
62           return
63           
64         case "types"
65           if (isnull(RHS)) error("Types can't be nulled"); endif
66           if (1 == length (S))
67             %# perform explicit cast on each column
68             df._data = cellfun (@(x) cast (x, RHS), df._data, 
69                                 "UniformOutput", false);
70             df._type(1:end) = RHS;
71           else
72             if (~strcmp (S(2).type, '()'))
73               error ("Invalid internal type sub-access, use () instead");
74             endif 
75             if (length (S) > 2 || length (S(2).subs) > 1)
76               error("Types can only be changed as a whole");
77             endif
78             if (~isnumeric(S(2).subs{1}))
79               [indj, ncol, S(2).subs{1}] = df_name2idx\
80                   (df._name{2}, S(2).subs{1}, df._cnt(2), 'column');
81             else
82               indj = S(2).subs{1}; ncol = length (indj);
83             endif
84             df._data(indj) = cellfun (@(x) cast (x, RHS), df._data(indj), 
85                                       "UniformOutput", false);
86             df._type(indj) = {RHS};
87           endif
88           return
89           
90         case "source"
91           if (length(S) > 1)
92             df._src = feval (@subsasgn, df._src, S(2:end), RHS);
93           else
94             df._src = RHS;
95           endif
96           return
97
98         case "comment"
99           if (length(S) > 1)
100             df._cmt = feval (@subsasgn, df._cmt, S(2:end), RHS);
101           else
102             df._cmt = RHS;
103           endif
104           return
105           
106         otherwise
107           if (~ischar (S(1).subs))
108             error ("Congratulations. I didn't see how to produce this error");
109           endif
110           %# translate the name to column
111           [indc, ncol] = df_name2idx (df._name{2}, S(1).subs, \
112                                       df._cnt(2), 'column', true);
113           if (isempty(indc))
114             %# dynamic allocation
115             df = df_pad (df, 2, 1, class (RHS));
116             indc = df._cnt(2); ncol = 1;
117             df._name{2}(end) = S(1).subs;
118             df._name{2} = genvarname(df._name{2});
119             df._over{2}(end) = false;
120           endif
121           
122           if (length(S) > 1)
123             if (1 == length (S(2).subs)), %# add column reference
124               S(2).subs{2} = indc;
125             else
126               S(2).subs(2:3) = {indc, S(2).subs{2}};
127             endif
128           else
129             %# full assignement
130             S(2).type = '()'; S(2).subs = { '', indc, ':' };
131             if (ndims (RHS) < 3)
132               if (isnull (RHS))
133                 S(2).subs = {':', indc};
134               elseif (1 == size (RHS, 2))
135                 S(2).subs = { '', indc };
136               elseif (1 == ncol && 1 == size (df._data{indc}, 2))
137                 %# force the padding of the vector to a matrix 
138                 S(2).subs = {'', indc, [1:size(RHS, 2)]};
139               endif
140             endif
141           endif
142           %# do we need to "rotate" RHS ?
143           if (1 == ncol && ndims (RHS) < 3 \
144                 && size (RHS, 2) > 1)
145             RHS = reshape (RHS, [size(RHS, 1), 1, size(RHS, 2)]);
146           endif
147           df = df_matassign (df, S(2), indc, ncol, RHS);
148       endswitch
149       
150     case '()'
151       [indr, nrow, S(1).subs{1}] = df_name2idx (df._name{1}, S(1).subs{1}, \
152                                                 df._cnt(1), 'row');
153       if (isempty (indr) && df._cnt(1) > 0)
154         %# this is not an initial assignment
155         df = df; return;
156       endif
157       
158       if (length (S(1).subs) > 1)
159         if (~isempty (S(1).subs{2}))
160           [indc, ncol, S(1).subs{2}] = \
161               df_name2idx (df._name{2}, S(1).subs{2}, df._cnt(2), 'column');
162           %# if (isempty (indc) && df._cnt(2) > 0)
163           %# this is not an initial assignment
164           %# df = df; return;
165         else
166           [indc, ncol] = deal ([]);
167         endif
168       else
169         mz = max (cellfun (@length, df._rep));
170         [fullindr, fullindc, fullinds] = ind2sub ([df._cnt(1:2) mz], indr);
171         indr = unique( fullindr); indc = unique (fullindc); 
172         inds = unique (fullinds);
173         ncol = length (indc);
174         if (any (inds > 1))
175           S(1).subs{3} = inds;
176         endif
177       endif
178       
179       %# avoid passing ':' as selector on the two first dims
180       if (~isnull (RHS))
181         S(1).subs{1} = indr; S(1).subs{2} = indc;
182       endif
183
184       df = df_matassign (df, S, indc, ncol, RHS);
185       
186   endswitch
187   
188   %# disp("end of subasgn"); keyboard
189   
190 endfunction