comparison scripts/plot/stemleaf.m @ 16085:979ebfdd240d

[mq]: stemleaf
author Rik <rik@octave.org>
date Thu, 21 Feb 2013 17:51:43 -0800
parents 7398b2dd08cb
children 2b994ee38b1c
comparison
equal deleted inserted replaced
16083:7398b2dd08cb 16085:979ebfdd240d
19 ## see <http://www.gnu.org/licenses/>. 19 ## see <http://www.gnu.org/licenses/>.
20 20
21 21
22 ## -*- texinfo -*- 22 ## -*- texinfo -*-
23 ## @deftypefn {Function File} {} stemleaf (@var{x}) 23 ## @deftypefn {Function File} {} stemleaf (@var{x})
24 ## @deftypefnx {Function File} {@var{plot} =} stemleaf (@var{x}, @var{opt}) 24 ## @deftypefnx {Function File} {} stemleaf (@var{x}, @var{stem_sz})
25 ## 25 ## @deftypefnx {Function File} {@var{plotstr} =} stemleaf (@dots{})
26 ## Compute and display a stem and leaf plot of the vector @var{x}. 26 ## Compute and display a stem and leaf plot of the vector @var{x}.
27 ## 27 ##
28 ## The @var{x} vector is converted to integer by @var{x} = @code{fix} (@var{x}). 28 ## The input @var{x} should be a vector of integers. Any non-integer values
29 ## If an output argument is provided, the plot is returned as 29 ## will be converted to integer by @code{@var{x} = fix (@var{x})}. Each
30 ## an array of strings. The first element is the heading 30 ## element of @var{x} will be plotted with the last digit of the element as a
31 ## followed by an element for each stem. 31 ## leaf value and the remaining digits as the stem. For example, 123 will be
32 ## The default stem step is 10. 32 ## plotted with the stem @samp{12} and the leaf @samp{3}.
33 ## The @var{x} vector should be integers. It will be treated so that 33 ##
34 ## the last digit is the leaf value and the other digits are 34 ## The optional input @var{stem_sz} sets the width of each stem.
35 ## the stems. 35 ## The stem width is determined by @code{10^(@var{stem_sz} + 1)}.
36 ## The leaf digits are not sorted. If sorted leaf values 36 ## The default stem width is 10.
37 ## are wanted, use @code{sort} (@var{x}) before calling @code{stemleaf} (@var{x}). 37 ##
38 ## The stem and leaf plot is described in: Ch. 3, 38 ## With no return argument, the plot is immediately displayed. If an output
39 ## Exploratory Data Analysis by J. W. Tukey, Addison-Wesley, 1977. 39 ## argument is provided, the plot is returned as an array of strings.
40 ##
41 ## The leaf digits are not sorted. If sorted leaf values are desired, use
42 ## @code{@var{xs} = sort (@var{x})} before calling @code{stemleaf (@var{xs})}.
43 ##
44 ## The stem and leaf plot is described in: Ch. 3, @cite{Exploratory
45 ## Data Analysis} by J. W. Tukey, Addison-Wesley, 1977.
40 ## @seealso{hist, printd} 46 ## @seealso{hist, printd}
41 ## @end deftypefn 47 ## @end deftypefn
42 48
43 ## Author: Michael D. Godfrey <michaeldgodfrey@gmail.com> 49 ## Author: Michael D. Godfrey <michaeldgodfrey@gmail.com>
44 ## Description: Compute stem and leaf plot 50 ## Description: Compute stem and leaf plot
45 51
46 function varargout = stemleaf (x, stem_unit) 52 function plotstr = stemleaf (x, stem_sz)
47 ## Compute and display a stem and leaf plot of the vector x. The x 53 ## Compute and display a stem and leaf plot of the vector x. The x
48 ## vector is converted to integer by x = fix(x). If an output argument 54 ## vector is converted to integer by x = fix(x). If an output argument
49 ## is provided, the plot is returned as an array of strings. The 55 ## is provided, the plot is returned as an array of strings. The
50 ## first element is the heading followed by an element for each stem. 56 ## first element is the heading followed by an element for each stem.
51 ## 57 ##
52 ## The default stem step is 10. If stem_unit is provided the stem 58 ## The default stem step is 10. If stem_sz is provided the stem
53 ## step is set to: 10^(stem_unit+1) The x vector should be integers. 59 ## step is set to: 10^(stem_sz+1). The x vector should be integers.
54 ## It will be treated so that the last digit is the leaf value and the 60 ## It will be treated so that the last digit is the leaf value and the
55 ## other digits are the stems. 61 ## other digits are the stems.
56 ## 62 ##
57 ## When we first implemented stem and leaf plots in the early 1960's 63 ## When we first implemented stem and leaf plots in the early 1960's
58 ## there was some discussion about sorting vs. leaving the leaf 64 ## there was some discussion about sorting vs. leaving the leaf
59 ## entries in the original order in the data. We decided in favor or 65 ## entries in the original order in the data. We decided in favor of
60 ## sorting the leaves for most purposes. This is the choice 66 ## sorting the leaves for most purposes. This is the choice
61 ## implemented in the SNAP/IEDA system that was written at that time. 67 ## implemented in the SNAP/IEDA system that was written at that time.
62 ## 68 ##
63 ## SNAP/IEDA and particularly its stem and leaf plotting were further 69 ## SNAP/IEDA, and particularly its stem and leaf plotting, were further
64 ## developed by Hale Trotter, David Hoagland (at Princeton and MIT) 70 ## developed by Hale Trotter, David Hoagland (at Princeton and MIT),
65 ## and others. 71 ## and others.
66 ## 72 ##
67 ## Tukey, in EDA, generally uses unsorted leaves. In addition, he 73 ## Tukey, in EDA, generally uses unsorted leaves. In addition, he
68 ## described a wide range of additional display formats. This 74 ## described a wide range of additional display formats. This
69 ## implementation does not sort the leaves, but if the x vector is 75 ## implementation does not sort the leaves, but if the x vector is
70 ## sorted then the leaves come out sorted. A simple display format is 76 ## sorted then the leaves come out sorted. A simple display format is
71 ## used. 77 ## used.
72 ## 78 ##
73 ## I doubt if providing other options is worthwhile. The code can 79 ## I doubt if providing other options is worthwhile. The code can
74 ## quite easily be modified to provide specific display results. Or, 80 ## quite easily be modified to provide specific display results. Or,
75 ## the returned output string can be edited. The returned output is an 81 ## the returned output string can be edited. The returned output is an
76 ## array of strings with each row containing a line of the plot 82 ## array of strings with each row containing a line of the plot
77 ## preceded by the lines of header text as the first row. This 83 ## preceded by the lines of header text as the first row. This
78 ## facilitates annotation. 84 ## facilitates annotation.
79 ## 85 ##
80 ## Note that the code has some added complexity due to the need to 86 ## Note that the code has some added complexity due to the need to
81 ## distinguish both + and - 0 stems. The +- stem values are essential 87 ## distinguish both + and - 0 stems. The +- stem values are essential
82 ## for all plots which span 0. After dealing with +-0 stems, the added 88 ## for all plots which span 0. After dealing with +-0 stems, the added
83 ## complexity of putting +- data values in the correct stem is minor, 89 ## complexity of putting +- data values in the correct stem is minor,
84 ## but the sign of 0 leaves must be checked. And, the cases where the 90 ## but the sign of 0 leaves must be checked. And, the cases where the
85 ## stems start or end at +- 0 must also be considered. 91 ## stems start or end at +- 0 must also be considered.
86 ## 92 ##
87 ## The fact that IEEE floating point defines +- 0 helps make this 93 ## The fact that IEEE floating point defines +- 0 helps make this
88 ## easier. 94 ## easier.
89 ## 95 ##
90 ##
91 ## Michael D. Godfrey January 2013 96 ## Michael D. Godfrey January 2013
92 97
93 ## More could be implemented for better data scaling. And, of course, 98 ## More could be implemented for better data scaling. And, of course,
94 ## other options for the kinds of plots described by Tukey could be 99 ## other options for the kinds of plots described by Tukey could be
95 ## provided. This may best be left to users. 100 ## provided. This may best be left to users.
96 101
97 if (nargin >= 2) 102 if (nargin < 1 || nargin > 2)
98 stem_step = 10^(stem_unit+1); 103 print_usage ();
104 endif
105
106 if (! isvector (x))
107 error ("stemleaf: X must be a vector");
108 endif
109
110 if (isinteger (x))
111 ## Avoid use of int32 because rounding rules do not use fix():
112 ## floor (int32 (-44)/10) == -4 and floor (int32 (-46)/10) = -5 !!!
113 x = single (x);
114 elseif (isfloat (x))
115 xint = fix (x);
116 if (any (x != xint))
117 warning ("stemleaf: X truncated to integer values");
118 x = xint;
119 endif
99 else 120 else
121 error ("stemleaf: X must be a numeric vector");
122 endif
123
124 if (nargin == 1)
100 stem_step = 10; 125 stem_step = 10;
101 endif 126 else
102 if (any (x == int32 (x)) == 0) 127 if (isscalar (stem_sz) && stem_sz >= 0 && isreal (stem_sz))
103 printf ('Input vector truncated to integer values.\n') 128 stem_step = 10^(stem_sz+1);
104 x = fix (x); 129 else
105 endif 130 error ("stemleaf: STEM_SZ must be a real integer >= 0");
106 131 endif
107 ## Avoid use of int32 due to: 132 endif
108 133
109 ## floor (int32 (-44)/10) == -4 and floor (int32 (-46)/10) = -5 !!! 134 ## Note that IEEE 754 states that -+ 0 should compare equal. This has
110 ## x = sort (fix (x)); % User can decide about sorting x.
111 ## x = fix (x);
112 ## %Adjust scale if too small.
113 ## while any(abs((fix(x) - x)) >= abs(x/100))
114 ## x =10*x;
115 ## endwhile
116
117 ## Note that IEEE 754 states that -+ 0 should compare equal. This has
118 ## led to C sort (and therefore Octave) treating them as equal. Thus, 135 ## led to C sort (and therefore Octave) treating them as equal. Thus,
119 ## sort([ -1 0 -0 1]) yields: -1 0 -0 1. and, sort([-1 -0 0 1]) 136 ## sort([-1 0 -0 1]) yields [-1 0 -0 1], and sort([-1 -0 0 1])
120 ## yields: -1 -0 0 1. This means that stem-and-leaf plotting cannot 137 ## yields: [-1 -0 0 1]. This means that stem-and-leaf plotting cannot
121 ## rely on sort to order the data as needed for display. 138 ## rely on sort to order the data as needed for display.
122 139 ## This also applies to min()/max() so these routines can't be relied
123 if (all((sort(x) == x)) == 1) 140 ## upon if the max or min is -+ 0.
124 hsort = 'sorted.'; 141
142 if (issorted (x))
143 hsort = "sorted.";
125 else 144 else
126 hsort = 'unsorted.'; 145 hsort = "unsorted.";
127 endif 146 endif
128 nx = max (size (x)); 147
129 ## Determine stem values 148 ## Determine stem values
130 if (min(x) < 0) 149 min_x = min (x);
131 if (signbit(max(x)) == 0) # max is positive 150 max_x = max (x);
132 stems = [fix(min(x)/stem_step)-1 : -1 -0]; 151 if (min_x > 0) # all stems > 0
133 stems = [stems 0 : fix(max(x)/stem_step)+1 ]; 152 stems = [fix(min(x)/stem_step) : (fix(max(x)/stem_step)+1)];
134 else 153 elseif (max_x < 0) # all stems < 0
135 if (max(x) < 0) 154 stems = [(fix(min_x/stem_step)-1) : fix(max_x/stem_step)];
136 stems = [(fix(min(x)/stem_step)-1) : fix(max(x)/stem_step)]; 155 elseif (min_x < 0 && max_x > 0) # range crosses 0
156 stems = [(fix(min_x/stem_step)-1) : -1 , -0];
157 stems = [stems, 0 : fix(max_x/stem_step)+1 ];
158 else # range includes a zero which may be +0 or -0
159 if (min_x == 0)
160 if (any (x == 0 & signbit (x)))
161 min_x = -0;
137 else 162 else
138 stems = [(fix(min(x)/stem_step)-1) : -1 -0]; 163 min_x = +0;
139 stems = [stems 0 : fix(max(x)/stem_step)]; 164 endif
140 endif 165 endif
141 endif 166 if (max_x == 0)
142 else # All stems are > 0 167 if (any (x == 0 & ! signbit (x)))
143 stems = [fix(min(x)/stem_step) : fix(max(x)/stem_step) + 1]; 168 max_x = +0;
144 endif 169 else
145 ##stems 170 max_x = -0;
146 ##x 171 endif
147 nstems = max(size(stems)); 172 endif
173 stems = [];
174 if (signbit (min_x))
175 stems = [(fix(min_x/stem_step)-1) : -1 , -0];
176 endif
177 if (! signbit (max_x))
178 stems = [stems, 0 : fix(max_x/stem_step)+1 ];
179 endif
180 endif
181
182 nx = numel (x);
183 nstems = numel (stems);
148 ## compute hinges at +- 1.5 * quartiles 184 ## compute hinges at +- 1.5 * quartiles
149 ## this requires sorted data! 185 ## this requires sorted data!
150 xs = sort (x); # Note that sort preserves -0 186 xs = sort (x); # Note that sort preserves -0
151 threeh = 1.5; 187 j = fix (nx/4) + 1;
152 two = 2.0;
153 j = idivide(nx, 4, "fix") + 1; # Use F95 truncation.
154 k = nx - j + 1; 188 k = nx - j + 1;
155 hl = xs (j); 189 hl = xs(j);
156 hu = xs (k); 190 hu = xs(k);
157 if ( (nx + 1) == (4 * j) ) 191 ## FIXME: Is this really the only case where we want to average
158 hl = (xs (j + 1) + hl) / two; 192 ## values to determine the quartile?
159 hu = (xs (k - 1) + hu) / two; 193 if ( (nx + 1) == (4 * j) )
160 endif 194 hl = (xs(j + 1) + hl) / 2;
161 195 hu = (xs(k - 1) + hu) / 2;
162 ## :::::::: determine h-spread (dh) and fences :::::::: 196 endif
197
198 ## determine h-spread (dh) and fences
163 dh = hu - hl; 199 dh = hu - hl;
164 fu = hu + threeh * dh; 200 fu = hu + 1.5 * dh;
165 fl = hl - threeh * dh; 201 fl = hl - 1.5 * dh;
166 202
167 ## :::::::: find value adjacent to lower fence :::::::: 203 ## find value adjacent to lower fence
168 for i = 1:j 204 for i = 1:j
169 if ( xs (i) >= fl ) 205 if (xs(i) >= fl)
170 continue; 206 break;
171 endif 207 endif
172 endfor 208 endfor
173 ilow = i; 209 xlo = xs(i);
174 xlo = xs (ilow); 210
175 211 ## find value adjacent to upper fence
176 ## :::::::: find value adjacent to upper fence :::::::: 212 for i = 1:j
177 for i = 1:j 213 if (xs(nx -i + 1) <= fu)
178 if ( xs (nx -i + 1) <= fu ) 214 break;
179 continue;
180 endif 215 endif
181 endfor 216 endfor
182 217 xhi = xs(nx - i + 1);
183 ihi = nx - i + 1; 218
184 xhi = xs (ihi); 219 ## Summary at start of output:
185 220 plot_out = sprintf ("stem step: %i, data: %s", stem_step, hsort);
186 ## Heading for output: 221 plot_out = [plot_out; sprintf("Hinges: lo: %g, hi: %g", xlo, xhi)];
187 plot_out = ""; 222 plot_out = [plot_out; " "];
188 plot_out = [plot_out sprintf("stem step: %i, data: %s\nHinges: lo: %g, hi: %g\n",
189 stem_step, hsort, xlo, xhi)];
190 223
191 ## This may appear to be a good place to use vectorization using the 224 ## This may appear to be a good place to use vectorization using the
192 ## stem and data arrays but the necessary special case treatment of 0 225 ## stem and data arrays but the necessary special case treatment of 0
193 ## and -0 seems to result in little reduction of complexity, and since 226 ## and -0 seems to result in little reduction of complexity, and since
194 ## this algorithm is for small data vectors only there would be 227 ## this algorithm is for small data vectors only there would be
195 ## practically no performance improvement. 228 ## practically no performance improvement.
196 229
197 ## Determine leaves for each stem: 230 ## Determine leaves for each stem:
198 for kx = 2:nstems 231 for kx = 2:nstems
199 line_out = ""; 232 line = "";
200 steml = ""; 233 steml = "";
201 ## Build a string of leaf digits for stem(kx) if stem(kx) <= 0, or 234 ## Build a string of leaf digits for
235 ## stem(kx) if stem(kx) <= 0, or
202 ## stem(kx-1) if stem(kx) > 0 236 ## stem(kx-1) if stem(kx) > 0
203 237
204 ## stems -+ 0 have to be handled as special cases. 238 ## stems -+ 0 have to be handled as special cases.
205 for xi = 1:nx 239 for xi = 1:nx
206 if(signbit(stems(kx)) != 0) 240 if (signbit (stems(kx)) != 0)
207 t1 = ((x(xi) <= stems(kx)*10) && (x(xi) > (stems(kx-1)*10))); 241 t1 = ((x(xi) <= stems(kx)*10) && (x(xi) > (stems(kx-1)*10)));
208 else 242 else
209 t1 = ((x(xi) < stems(kx)*10) && (x(xi) >= (stems(kx-1)*10))); 243 t1 = ((x(xi) < stems(kx)*10) && (x(xi) >= (stems(kx-1)*10)));
210 endif 244 endif
211 ## Special tests for stem -+ 0 245 ## Special tests for stem -+ 0
212 if ((stems(kx) == 0) && signbit(stems(kx)) && (x(xi) == 0)) && !signbit(x(xi)) 246 if ((stems(kx) == 0)
247 && signbit (stems(kx)) && (x(xi) == 0)) && !signbit (x(xi))
213 t1 = 0; 248 t1 = 0;
214 endif 249 endif
215 if ((stems(kx-1) == 0) && !signbit(stems(kx-1)) && (x(xi) == 0)) && signbit(x(xi)) 250 if ((stems(kx-1) == 0)
251 && !signbit (stems(kx-1)) && (x(xi) == 0)) && signbit (x(xi))
216 t1 = 0; 252 t1 = 0;
217 endif 253 endif
218 ## Create line as a string 254 ## Create line as a string
219 if t1 255 if (t1)
220 if (stems(kx) <= 0) 256 if (stems(kx) <= 0)
221 xz = abs (x(xi) - stems(kx)*10); 257 xz = abs (x(xi) - stems(kx)*10);
222 else 258 else
223 xz = abs (x(xi) - stems(kx-1)*10); 259 xz = abs (x(xi) - stems(kx-1)*10);
224 endif 260 endif
225 if ((stems(kx) == 0) && signbit(stems(kx))) 261 if ((stems(kx) == 0) && signbit (stems(kx)))
226 steml = [steml sprintf("%d", abs(x(xi) - stems(kx)*10))]; 262 steml = [steml sprintf("%d", abs(x(xi) - stems(kx)*10))];
227 else 263 else
228 steml = [steml sprintf("%d", xz)]; 264 steml = [steml sprintf("%d", xz)];
229 endif 265 endif
230 endif % t1 266 endif # t1
231 endfor % xi = 1:nx 267 endfor # xi = 1:nx
232 268
233 ## Set correct -0 269 ## Set correct -0
234 if ((stems(kx) == 0) && signbit(stems(kx))) 270 if ((stems(kx) == 0) && signbit (stems(kx)))
235 line_out = [line_out sprintf(" -0 | %s", steml)]; % -0 stem. 271 line = [line sprintf(" -0 | %s", steml)]; # -0 stem.
236 else 272 else
237 if( stems(kx) < 0) 273 if (stems(kx) < 0)
238 line_out = [line_out sprintf("%4d | %s", stems(kx), steml)]; 274 line = [line sprintf("%4d | %s", stems(kx), steml)];
239 else 275 else
240 if stems(kx) > 0 276 if (stems(kx) > 0)
241 line_out = [line_out sprintf("%4d | %s", stems(kx-1), steml)]; 277 line = [line sprintf("%4d | %s", stems(kx-1), steml)];
242 endif 278 endif
243 endif 279 endif
244 endif 280 endif
245 plot_out = [plot_out; line_out]; 281 plot_out = [plot_out; line];
246 endfor % kx = 2:nstems 282 endfor # kx = 2:nstems
283
247 if (nargout == 0) 284 if (nargout == 0)
248 rows = size (plot_out)(1); 285 disp (plot_out);
249 cols = size (plot_out)(2);
250 for k = 1:rows
251 printf("%s\n", plot_out(k,1:cols));
252 endfor
253 else 286 else
254 varargout{1} = plot_out; 287 plotstr = plot_out;
255 endif 288 endif
289
256 endfunction 290 endfunction
291
257 292
258 %!demo 293 %!demo
259 %! ## Unsorted plot: 294 %! ## Unsorted plot:
260 %! x = [-22 12 -28 52 39 -2 12 10 11 11 42 38 44 18 44]; 295 %! x = [-22 12 -28 52 39 -2 12 10 11 11 42 38 44 18 44];
261 %! stemleaf (x, 0); 296 %! stemleaf (x);
262 297
263 %!demo 298 %!demo
264 %! ## Sorted leaves: 299 %! ## Sorted leaves:
265 %! x = [-22 12 -28 52 39 -2 12 10 11 11 42 38 44 18 44]; 300 %! x = [-22 12 -28 52 39 -2 12 10 11 11 42 38 44 18 44];
266 %! y = sort(x); 301 %! y = sort (x);
267 %! stemleaf (y, 0); 302 %! stemleaf (y);
268 303
269 %!demo 304 %!demo
270 %! ## More data (sorted) 305 %! ## Sorted leaves (large dataset):
271 %! x = [-22 12 -28 52 39 -2 12 10 11 11 42 38 44 18 44 37 113 124 37 48 127 36 29 31 125 139 131 115 105 132 104 123 35 113 122 42 117 119 58 109 23 105 63 27 44 105 99 41 128 121 116 125 32 61 37 127 29 113 121 58 114 126 53 114 96 25 109 7 31 141 46 -13 71 43 117 116 27 7 68 40 31 115 124 42 128 52 71 118 117 38 27 106 33 117 116 111 40 119 47 105 57 122 109 124 115 43 120 43 27 27 18 28 48 125 107 114 34 133 45 120 30 127 31 116 146 21 23 30 10 20 21 30 0 100 110 1 20 0 ]; 306 %! x = [-22 12 -28 52 39 -2 12 10 11 11 42 38 44 18 44 37 113 124 37 48 127 \
272 %! y = sort(x); 307 %! 36 29 31 125 139 131 115 105 132 104 123 35 113 122 42 117 119 58 109 \
273 %! stemleaf (y, 0); 308 %! 23 105 63 27 44 105 99 41 128 121 116 125 32 61 37 127 29 113 121 58 \
309 %! 114 126 53 114 96 25 109 7 31 141 46 -13 71 43 117 116 27 7 68 40 31 \
310 %! 115 124 42 128 52 71 118 117 38 27 106 33 117 116 111 40 119 47 105 57\
311 %! 122 109 124 115 43 120 43 27 27 18 28 48 125 107 114 34 133 45 120 30 \
312 %! 127 31 116 146 21 23 30 10 20 21 30 0 100 110 1 20 0];
313 %! y = sort (x);
314 %! stemleaf (y);
315
316 %!demo
317 %! ## Gaussian leaves:
318 %! x = fix (30 * randn (300,1));
319 %! stemleaf (x);
274 320
275 %!test 321 %!test
276 %! ## test minus to plus 322 %! ## test minus to plus
277 %! x = [-22 12 -28 52 39 -2 12 10 11 11 42 38 44 18 44 37 113 124 37 48 127 36 29 31 125 139 131 115 105 132 104 123 35 113 122 42 117 119 58 109 23 105 63 27 44 105 99 41 128 121 116 125 32 61 37 127 29 113 121 58 114 126 53 114 96 25 109 7 31 141 46 -13 71 43 117 116 27 7 68 40 31 115 124 42 128 52 71 118 117 38 27 106 33 117 116 111 40 119 47 105 57 122 109 124 115 43 120 43 27 27 18 28 48 125 107 114 34 133 45 120 30 127 31 116 146 21 23 30 10 20 21 30 0 100 110 1 20 0 ]; 323 %! x = [-22 12 -28 52 39 -2 12 10 11 11 42 38 44 18 44 37 113 124 37 48 127 \
278 %! x = sort(x); 324 %! 36 29 31 125 139 131 115 105 132 104 123 35 113 122 42 117 119 58 109 \
279 %! r2 = ["stem step: 10, data: sorted.\nHinges: lo: 30, hi: 116\n";... 325 %! 23 105 63 27 44 105 99 41 128 121 116 125 32 61 37 127 29 113 121 58 \
280 %! " -2 | 82";" -1 | 3";" -0 | 2";" 0 | 00177";... 326 %! 114 126 53 114 96 25 109 7 31 141 46 -13 71 43 117 116 27 7 68 40 31 \
281 %! " 1 | 00112288";" 2 | 001133577777899";... 327 %! 115 124 42 128 52 71 118 117 38 27 106 33 117 116 111 40 119 47 105 57\
282 %! " 3 | 000111123456777889";" 4 | 00122233344456788";... 328 %! 122 109 124 115 43 120 43 27 27 18 28 48 125 107 114 34 133 45 120 30 \
283 %! " 5 | 223788";" 6 | 138";" 7 | 11";" 8 | ";... 329 %! 127 31 116 146 21 23 30 10 20 21 30 0 100 110 1 20 0];
284 %! " 9 | 69";" 10 | 04555567999";" 11 | 0133344455566667777899";... 330 %! x = sort (x);
285 %! " 12 | 0011223444555677788";" 13 | 1239";" 14 | 16"]; 331 %! rexp = char (
286 %! rx = stemleaf (x, 0); 332 %! "stem step: 10, data: sorted." ,
287 %! assert(r2, rx); 333 %! "Hinges: lo: -28, hi: 146" ,
334 %! " " ,
335 %! " -2 | 82" ,
336 %! " -1 | 3" ,
337 %! " -0 | 2" ,
338 %! " 0 | 00177" ,
339 %! " 1 | 00112288" ,
340 %! " 2 | 001133577777899" ,
341 %! " 3 | 000111123456777889" ,
342 %! " 4 | 00122233344456788" ,
343 %! " 5 | 223788" ,
344 %! " 6 | 138" ,
345 %! " 7 | 11" ,
346 %! " 8 | " ,
347 %! " 9 | 69" ,
348 %! " 10 | 04555567999" ,
349 %! " 11 | 0133344455566667777899",
350 %! " 12 | 0011223444555677788" ,
351 %! " 13 | 1239" ,
352 %! " 14 | 16" );
353 %! r = stemleaf (x, 0);
354 %! assert (r, rexp);
355
288 %!test 356 %!test
289 %! ## positive values above 0 357 %! ## positive values above 0
290 %! x = [22 12 28 52 39 12 11 11 42 38 44 18 44 ]; 358 %! x = [22 12 28 52 39 12 11 11 42 38 44 18 44];
291 %! r2 = ["stem step: 10, data: unsorted.\nHinges: lo: 12, hi: 42\n";... 359 %! rexp = char (
292 %! " 1 | 22118";" 2 | 28";" 3 | 98";" 4 | 244";" 5 | 2"]; 360 %! "stem step: 10, data: unsorted." ,
293 %! rx = stemleaf (x, 0); 361 %! "Hinges: lo: 11, hi: 52" ,
294 %! assert(r2, rx); 362 %! " " ,
363 %! " 1 | 22118" ,
364 %! " 2 | 28" ,
365 %! " 3 | 98" ,
366 %! " 4 | 244" ,
367 %! " 5 | 2" );
368 %! r = stemleaf (x);
369 %! assert (r, rexp);
370
295 %!test 371 %!test
296 %! ## negative values below 0 372 %! ## negative values below 0
297 %! x = [22 12 28 52 39 12 11 11 42 38 44 18 44]; 373 %! x = [22 12 28 52 39 12 11 11 42 38 44 18 44];
298 %! x = -x; 374 %! x = -x;
299 %! r2 = ["stem step: 10, data: unsorted.\nHinges: lo: -42, hi: -12\n";... 375 %! rexp = char (
300 %! " -5 | 2";" -4 | 244";" -3 | 98";" -2 | 28";" -1 | 22118"]; 376 %! "stem step: 10, data: unsorted." ,
301 %! rx = stemleaf (x, 0); 377 %! "Hinges: lo: -52, hi: -11" ,
302 %! assert(r2, rx); 378 %! " " ,
379 %! " -5 | 2" ,
380 %! " -4 | 244" ,
381 %! " -3 | 98" ,
382 %! " -2 | 28" ,
383 %! " -1 | 22118" );
384 %! r = stemleaf (x);
385 %! assert (r, rexp);
386
303 %!test 387 %!test
304 %! ## positive values from 0 388 %! ## positive values from 0
305 %! x = [22 12 28 52 39 2 12 0 11 11 42 38 44 18 44]; 389 %! x = [22 12 28 52 39 2 12 0 11 11 42 38 44 18 44];
306 %! r2 = ["stem step: 10, data: unsorted.\nHinges: lo: 11, hi: 42\n";... 390 %! rexp = char (
307 %! " 0 | 20";" 1 | 22118";" 2 | 28";" 3 | 98";" 4 | 244";" 5 | 2"]; 391 %! "stem step: 10, data: unsorted." ,
308 %! rx = stemleaf (x, 0); 392 %! "Hinges: lo: 0, hi: 52" ,
309 %! assert(r2, rx); 393 %! " " ,
394 %! " 0 | 20" ,
395 %! " 1 | 22118" ,
396 %! " 2 | 28" ,
397 %! " 3 | 98" ,
398 %! " 4 | 244" ,
399 %! " 5 | 2" );
400 %! r = stemleaf (x);
401 %! assert (r, rexp);
402
310 %!test 403 %!test
311 %! ## negative values from 0 404 %! ## negative values from 0
312 %! x = [22 12 28 52 39 2 12 0 11 11 42 38 44 18 44]; 405 %! x = [22 12 28 52 39 2 12 0 11 11 42 38 44 18 44];
313 %! x = -x; 406 %! x = -x;
314 %! r2 = ["stem step: 10, data: unsorted.\nHinges: lo: -42, hi: -11\n";... 407 %! rexp = char (
315 %! " -5 | 2";" -4 | 244";" -3 | 98";" -2 | 28";" -1 | 22118";" -0 | 20"]; 408 %! "stem step: 10, data: unsorted." ,
316 %! rx = stemleaf (x, 0); 409 %! "Hinges: lo: -52, hi: -0" ,
317 %! assert(r2, rx); 410 %! " " ,
318 411 %! " -5 | 2" ,
412 %! " -4 | 244" ,
413 %! " -3 | 98" ,
414 %! " -2 | 28" ,
415 %! " -1 | 22118" ,
416 %! " -0 | 20" );
417 %! r = stemleaf (x);
418 %! assert (r, rexp);
419
420 %!test
421 %! ## both +0 and -0 present
422 %! x = [-9 -7 -0 0];
423 %! rexp = char (
424 %! "stem step: 10, data: sorted." ,
425 %! "Hinges: lo: -9, hi: 0" ,
426 %! " " ,
427 %! " -0 | 970" ,
428 %! " 0 | 0" );
429 %! r = stemleaf (x);
430 %! assert (r, rexp);
431
432 ## Test input validation
433 %!error stemleaf ()
434 %!error stemleaf (1, 2, 3)
435 %!error <X must be a vector> stemleaf (ones (2,2))
436 %!warning <X truncated to integer values> tmp = stemleaf ([0 0.5 1]);
437 %!error <X must be a numeric vector> stemleaf ("Hello World")
438 %!error <STEM_SZ must be a real integer> stemleaf (1, ones (2,2))
439 %!error <STEM_SZ must be a real integer> stemleaf (1, -1)
440 %!error <STEM_SZ must be a real integer> stemleaf (1, 1+i)
441