1 /* PSPP - a program for statistical analysis.
2 Copyright (C) 2008, 2009, 2011 Free Software Foundation, Inc.
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>. */
19 #include "box-whisker.h"
24 #include "data/case.h"
25 #include "data/data-out.h"
26 #include "data/val-type.h"
27 #include "data/variable.h"
28 #include "libpspp/assertion.h"
29 #include "libpspp/cast.h"
30 #include "libpspp/str.h"
31 #include "math/order-stats.h"
32 #include "math/tukey-hinges.h"
34 #include "gl/xalloc.h"
37 destroy (struct statistic
*s
)
39 struct box_whisker
*bw
= UP_CAST (s
, struct box_whisker
, parent
.parent
);
40 struct order_stats
*os
= &bw
->parent
;
43 for (ll
= ll_head (&bw
->outliers
); ll
!= ll_null (&bw
->outliers
);)
45 struct outlier
*e
= ll_data (ll
, struct outlier
, ll
);
49 ds_destroy (&e
->label
);
59 acc (struct statistic
*s
, const struct ccase
*cx
,
60 double c UNUSED
, double cc UNUSED
, double y
)
62 struct box_whisker
*bw
= UP_CAST (s
, struct box_whisker
, parent
.parent
);
66 if (y
> bw
->hinges
[2] + bw
->step
) /* Upper outlier */
68 extreme
= (y
> bw
->hinges
[2] + 2 * bw
->step
) ;
71 else if (y
< bw
->hinges
[0] - bw
->step
) /* Lower outlier */
73 extreme
= (y
< bw
->hinges
[0] - 2 * bw
->step
) ;
76 else /* Not an outlier */
78 if (bw
->whiskers
[0] == SYSMIS
)
81 if (y
> bw
->whiskers
[1])
89 o
= xzalloc (sizeof *o
) ;
92 ds_init_empty (&o
->label
);
96 char *s
= data_out (case_data_idx (cx
, bw
->id_idx
),
97 var_get_encoding (bw
->id_var
),
98 var_get_print_format (bw
->id_var
));
100 ds_put_cstr (&o
->label
, s
);
105 ds_put_format (&o
->label
,
107 (casenumber
) case_data_idx (cx
, bw
->id_idx
)->f
);
110 ll_push_head (&bw
->outliers
, &o
->ll
);
114 box_whisker_whiskers (const struct box_whisker
*bw
, double whiskers
[2])
116 whiskers
[0] = bw
->whiskers
[0];
117 whiskers
[1] = bw
->whiskers
[1];
121 box_whisker_hinges (const struct box_whisker
*bw
, double hinges
[3])
123 hinges
[0] = bw
->hinges
[0];
124 hinges
[1] = bw
->hinges
[1];
125 hinges
[2] = bw
->hinges
[2];
128 const struct ll_list
*
129 box_whisker_outliers (const struct box_whisker
*bw
)
131 return &bw
->outliers
;
135 Create a box_whisker struct, suitable for generating a boxplot.
137 TH are the tukey hinges of the dataset.
139 id_idx is the index into the casereader which will be used to label
141 id_var is the variable from which that label came, or NULL
144 box_whisker_create (const struct tukey_hinges
*th
,
145 size_t id_idx
, const struct variable
*id_var
)
147 struct box_whisker
*w
= xzalloc (sizeof (*w
));
148 struct order_stats
*os
= &w
->parent
;
149 struct statistic
*stat
= &os
->parent
;
153 stat
->destroy
= destroy
;
154 stat
->accumulate
= acc
;
156 tukey_hinges_calculate (th
, w
->hinges
);
161 w
->step
= (w
->hinges
[2] - w
->hinges
[0]) * 1.5;
163 w
->whiskers
[1] = w
->hinges
[2];
164 w
->whiskers
[0] = SYSMIS
;
166 ll_init (&w
->outliers
);