"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "lib/src/dataset.c" between
gretl-2020a.tar.xz and gretl-2020b.tar.xz

About: gretl (Gnu Regression, Econometrics and Time-series Library) is a cross-platform statistical package mainly for econometric analysis.

dataset.c  (gretl-2020a.tar.xz):dataset.c  (gretl-2020b.tar.xz)
skipping to change at line 938 skipping to change at line 938
for (i=1; i<dset->v; i++) { for (i=1; i<dset->v; i++) {
if (real_periodic_dummy(dset->Z[i], oldn, &pd, &offset, &xon, &xoff)) { if (real_periodic_dummy(dset->Z[i], oldn, &pd, &offset, &xon, &xoff)) {
for (t=oldn; t<dset->n; t++) { for (t=oldn; t<dset->n; t++) {
dset->Z[i][t] = ((t - offset) % pd)? xoff : xon; dset->Z[i][t] = ((t - offset) % pd)? xoff : xon;
} }
} }
} }
} }
/** /* regular, not panel-time, version */
* dataset_add_observations:
* @dset: pointer to dataset.
* @n: number of observations to add.
* @opt: use OPT_A to attempt to recognize and
* automatically extend simple deterministic variables such
* as a time trend and periodic dummy variables;
* use OPT_D to drop any observation markers rather than
* expanding the set of markers and padding it out with
* dummy values.
*
* Extends all series in the dataset by the specified number of
* extra observations. The added values are initialized to
* the missing value code, #NADBL, with the exception of
* simple deterministic variables when OPT_A is given.
*
* Returns: 0 on success, non-zero code on error.
*/
int dataset_add_observations (DATASET *dset, int n, gretlopt opt) static int real_dataset_add_observations (DATASET *dset, int n,
gretlopt opt)
{ {
double *x; double *x;
int oldn = dset->n; int oldn = dset->n;
int i, t, bign; int i, t, bign;
int err = 0; int err = 0;
if (dset_zcols_borrowed(dset)) { if (dset_zcols_borrowed(dset)) {
fprintf(stderr, "*** Internal error: modifying borrowed data\n"); fprintf(stderr, "*** Internal error: modifying borrowed data\n");
return E_DATA; return E_DATA;
} }
skipping to change at line 1020 skipping to change at line 1004
maybe_extend_trends(dset, oldn); maybe_extend_trends(dset, oldn);
maybe_extend_dummies(dset, oldn); maybe_extend_dummies(dset, oldn);
} }
/* does daily data need special handling? */ /* does daily data need special handling? */
ntodate(dset->endobs, bign - 1, dset); ntodate(dset->endobs, bign - 1, dset);
return err; return err;
} }
static int panel_dataset_extend_time (DATASET *dset, int n)
{
double *utmp, *vtmp;
char **S = NULL;
int newT, oldT = dset->pd;
int oldn = dset->n;
int n_units;
int i, j, s, t, bign;
size_t usz, vsz;
int err = 0;
if (!dataset_is_panel(dset)) {
return E_PDWRONG;
}
if (dset_zcols_borrowed(dset)) {
fprintf(stderr, "*** Internal error: modifying borrowed data\n");
return E_DATA;
}
if (n <= 0) {
return 0;
}
n_units = oldn / oldT;
newT = oldT + n;
bign = n_units * newT;
usz = newT * sizeof *utmp;
vsz = bign * sizeof *vtmp;
utmp = malloc(usz);
if (utmp == NULL) {
return E_ALLOC;
}
if (dataset_has_markers(dset)) {
S = strings_array_new_with_length(bign, OBSLEN);
if (S == NULL) {
free(utmp);
return E_ALLOC;
}
}
for (i=0; i<dset->v; i++) {
int uconst = 1, utrend = 1, dtrend = 1;
double xbak = NADBL;
guint32 dt = 0, dbak = 0;
int ed_err;
vtmp = malloc(vsz);
if (vtmp == NULL) {
err = E_ALLOC;
goto bailout;
}
s = 0;
for (j=0; j<n_units; j++) {
for (t=0; t<oldT; t++) {
utmp[t] = dset->Z[i][s++];
if (dtrend) {
dt = epoch_day_from_ymd_basic(utmp[t]);
}
if (t == 0) {
xbak = utmp[t];
dbak = dt;
} else {
if (uconst && (utmp[t] != xbak)) {
uconst = 0;
}
if (utrend && (utmp[t] != xbak + 1)) {
utrend = 0;
}
if (dtrend && (dt != dbak + 1)) {
dtrend = 0;
}
}
xbak = utmp[t];
dbak = dt;
}
for (t=oldT; t<newT; t++) {
if (i == 0) {
utmp[t] = 1.0;
} else if (uconst) {
utmp[t] = utmp[t-1];
} else if (utrend) {
utmp[t] = utmp[t-1] + 1;
} else if (dtrend) {
dt = epoch_day_from_ymd_basic(utmp[t-1]);
utmp[t] = ymd_basic_from_epoch_day(dt+1, 0, &ed_err);
} else {
utmp[t] = NADBL;
}
}
memcpy(vtmp + j*newT, utmp, usz);
}
free(dset->Z[i]);
dset->Z[i] = vtmp;
}
if (S != NULL) {
int k = 0;
s = 0;
for (j=0; j<n_units; j++) {
for (t=0; t<newT; t++) {
if (t < oldT) {
strcpy(S[k], dset->S[s++]);
} else {
sprintf(S[k], "%d:%d", j+1, t+1);
}
k++;
}
}
strings_array_free(dset->S, oldn);
dset->S = S;
S = NULL;
}
if (dset->t2 == dset->n - 1) {
dset->t2 = bign - 1;
}
dataset_set_nobs(dset, bign);
dset->pd = newT;
ntodate(dset->endobs, bign - 1, dset);
bailout:
free(utmp);
if (S != NULL) {
strings_array_free(S, bign);
}
return err;
}
/**
* dataset_add_observations:
* @dset: pointer to dataset.
* @n: number of observations to add.
* @opt: use OPT_A to attempt to recognize and
* automatically extend simple deterministic variables such
* as a time trend and periodic dummy variables;
* use OPT_D to drop any observation markers rather than
* expanding the set of markers and padding it out with
* dummy values; use OPT_T to extend in the time dimension
* in the case of panel data.
*
* Extends all series in the dataset by the specified number of
* extra observations. The added values are initialized to
* the missing value code, #NADBL, with the exception of
* simple deterministic variables when OPT_A is given.
*
* Returns: 0 on success, non-zero code on error.
*/
int dataset_add_observations (DATASET *dset, int n, gretlopt opt)
{
if (opt & OPT_T) {
return panel_dataset_extend_time(dset, n);
} else {
return real_dataset_add_observations(dset, n, opt);
}
}
static int real_insert_observation (int pos, DATASET *dset) static int real_insert_observation (int pos, DATASET *dset)
{ {
double *x; double *x;
int n = dset->n + 1; int n = dset->n + 1;
int i, t; int i, t;
int err = 0; int err = 0;
for (i=0; i<dset->v; i++) { for (i=0; i<dset->v; i++) {
x = realloc(dset->Z[i], n * sizeof *x); x = realloc(dset->Z[i], n * sizeof *x);
if (x == NULL) { if (x == NULL) {
skipping to change at line 2520 skipping to change at line 2670
free(fset->Z[i]); free(fset->Z[i]);
fset->Z[i] = NULL; fset->Z[i] = NULL;
} }
err = shrink_dataset_to_size(fset, newv, DROP_SPECIAL); err = shrink_dataset_to_size(fset, newv, DROP_SPECIAL);
} }
} }
return err; return err;
} }
static void make_stack_label (char *label, char *s)
{
char *p = strstr(s, "--");
int len = strlen(s);
if (p == NULL) {
if (len > MAXLABEL - 1) {
strncat(label, s, MAXLABEL - 4);
strcat(label, "...");
} else {
strcat(label, s);
}
} else {
int llen = strlen(p);
char *q = strstr(p + 2, "--");
int sp = 1 + (q != NULL);
len++;
*p = '\0';
if (len + sp > MAXLABEL - 1) {
strncat(label, s, MAXLABEL - 4 - (llen + sp));
strcat(label, "...");
} else {
strcat(label, s);
}
strcat(label, " -");
if (q == NULL) {
strcat(label, p + 1);
} else {
strncat(label, p + 1, q - p - 1);
strcat(label, " ");
strcat(label, q);
}
}
}
static int get_stack_param_val (const char *s, const DATASET *dset)
{
int val = -1;
if (isdigit(*s)) {
val = atoi(s);
} else {
char vname[VNAMELEN];
int i, len = strcspn(s, " -");
if (len > VNAMELEN - 1) {
len = VNAMELEN - 1;
}
*vname = '\0';
strncat(vname, s, len);
if (gretl_is_scalar(vname)) {
val = gretl_scalar_get_value(vname, NULL);
} else {
i = series_index(dset, vname);
if (i < dset->v) {
val = (int) dset->Z[i][0];
}
}
}
return val;
}
static int get_optional_offset (const char *s, const DATASET *dset,
int *err)
{
const char *p = strstr(s, "--o");
int off = 0;
if (p != NULL) {
if (strncmp(p, "--offset=", 9)) {
*err = E_PARSE;
} else {
off = get_stack_param_val(p + 9, dset);
if (off < 0 || off > dset->n - 1) {
*err = E_DATA;
}
}
}
return off;
}
static int get_optional_length (const char *s, const DATASET *dset,
int *err)
{
const char *p = strstr(s, "--l");
int len = 0;
if (p != NULL) {
if (strncmp(p, "--length=", 9)) {
*err = E_PARSE;
} else {
len = get_stack_param_val(p + 9, dset);
if (len < 0 || len > dset->n) {
*err = E_DATA;
}
}
}
return len;
}
/* Apparatus for stacking variables (e.g. in case of panel /* Apparatus for stacking variables (e.g. in case of panel
data that were read in "wrongly"). data that were read in "wrongly").
*/ */
static int missing_tail (const double *x, int n) static int missing_tail (const double *x, int n)
{ {
int i, nmiss = 0; int i, nmiss = 0;
for (i=n-1; i>=0; i--) { for (i=n-1; i>=0; i--) {
if (na(x[i])) { if (na(x[i])) {
nmiss++; nmiss++;
} else { } else {
break; break;
} }
} }
return nmiss; return nmiss;
} }
static int *list_to_array (const int *list, int *err)
{
int nv = list[0];
int *arr = NULL;
if (nv <= 0) {
*err = E_DATA;
} else {
arr = malloc(nv * sizeof *arr);
if (arr == NULL) {
*err = E_ALLOC;
} else {
int i;
for (i=0; i<nv; i++) {
arr[i] = list[i+1];
}
}
}
return arr;
}
/** /**
* dataset_stack_variables: * build_stacked_series:
* @vname: name for new variable, to be produced by stacking. * @pstack: location for returning stacked series.
* @line: instructions for stacking existing variables. * @list: list of series to be stacked.
* @length: number of observations to use per input series (or 0 for auto).
* @offset: offset at which to start drawing observations.
* @dset: pointer to dataset. * @dset: pointer to dataset.
* @prn: printing apparatus.
* *
* Really for internal use. Don't worry about it. * Really for internal use. Don't worry about it.
* *
* Returns: 0 on success, non-zero code on error. * Returns: 0 on success, non-zero code on error.
*/ */
int dataset_stack_variables (const char *vname, const char *line, int build_stacked_series (double **pstack, int *list,
DATASET *dset, PRN *prn) int length, int offset,
DATASET *dset)
{ {
char vn1[VNAMELEN], vn2[VNAMELEN]; double *xstack = NULL;
char format[16]; int nv, oldn, bign;
char *p, *s = NULL, *scpy = NULL; int i, err = 0;
int *vnum = NULL;
int *stacklist = NULL;
double *bigx = NULL;
int i, v1 = 0, v2 = 0, nv = 0;
int done = 0;
int maxok, offset = 0;
int oldn, bign, genv;
int err = 0;
if (dset == NULL || dset->n == 0) { if (dset == NULL || dset->n == 0) {
return E_NODATA; return E_NODATA;
} else if (list == NULL || list[0] <= 0) {
return E_INVARG;
} else if (length + offset > dset->n) {
return E_INVARG;
} }
/* copy full "stack(...)" spec for later reference */ nv = list[0];
scpy = gretl_strdup(line);
if (scpy == NULL) {
return E_ALLOC;
}
line += 6; /* skip "stack(" */
if (*line == ',') {
free(scpy);
return E_PARSE;
}
/* copy active portion of line (we use strtok below) */
s = gretl_strdup(line);
if (s == NULL) {
free(scpy);
return E_ALLOC;
}
p = strrchr(s, ')');
if (p == NULL) {
err = E_PARSE;
goto bailout;
}
/* end of active portion of line */
*p = '\0';
genv = series_index(dset, vname);
/* do we have a named list? */
stacklist = get_list_by_name(s);
if (stacklist != NULL) {
nv = stacklist[0];
if (nv <= 0) {
err = E_DATA;
goto bailout;
}
vnum = list_to_array(stacklist, &err);
if (err) {
goto bailout;
}
done = 1;
}
if (!done) {
/* do we have a range of vars? */
sprintf(format, "%%%d[^.]..%%%ds", VNAMELEN-1, VNAMELEN-1);
if (sscanf(s, format, vn1, vn2) == 2) {
if (isdigit(*vn1) && isdigit(*vn2)) {
v1 = atoi(vn1);
v2 = atoi(vn2);
} else {
v1 = series_index(dset, vn1);
v2 = series_index(dset, vn2);
}
if (v1 >= 0 && v2 > v1 && v2 < dset->v) {
nv = v2 - v1 + 1;
} else {
fputs("stack vars: range is invalid\n", stderr);
err = E_DATA;
}
done = 1;
}
}
if (!done && strchr(s, '*') != NULL) {
/* or perhaps a wildcard thing? */
int *list = generate_list(s, dset, &err);
if (!err) {
nv = list[0];
vnum = list_to_array(list, &err);
free(list);
}
done = 1;
}
if (!done) {
/* or (special) a comma-separated list of vars? */
char *p = s;
while (*p) {
if (*p == ',') nv++;
p++;
}
nv++;
if (nv < 2) {
return E_PARSE;
}
vnum = malloc(nv * sizeof *vnum);
if (vnum == NULL) {
err = E_ALLOC;
}
for (i=0; i<nv && !err; i++) {
p = strtok((i == 0)? s : NULL, ",");
while (*p == ' ') p++;
if (isdigit(*p)) {
v1 = atoi(p);
} else {
v1 = series_index(dset, p);
}
if (v1 < 0 || v1 >= dset->v) {
err = E_UNKVAR;
} else {
vnum[i] = v1;
}
}
}
if (!err) {
/* get offset specified by user? */
offset = get_optional_offset(scpy, dset, &err);
}
if (!err) {
/* get length specified by user? */
maxok = get_optional_length(scpy, dset, &err);
}
#if PDEBUG #if PDEBUG
fprintf(stderr, "offset = %d, maxok = %d\n", offset, maxok); fprintf(stderr, "nv = %d, length = %d, offset = %d\n", nv, length, offset);
#endif #endif
if (!err && offset + maxok > dset->n) { if (length > 0) {
err = E_DATA; bign = nv * length;
}
if (err) {
goto bailout;
}
if (maxok > 0) {
bign = nv * maxok;
if (bign < dset->n) { if (bign < dset->n) {
bign = dset->n; bign = dset->n;
} }
} else { } else {
/* calculate required series length */ /* calculate required series length */
maxok = 0; length = 0;
for (i=0; i<nv; i++) { for (i=0; i<nv; i++) {
int j = (vnum == NULL)? i + v1 : vnum[i]; int j = list[i+1];
int ok = dset->n - missing_tail(dset->Z[j], dset->n); int ok = dset->n - missing_tail(dset->Z[j], dset->n); /* ?? */
if (ok > maxok) { if (ok > length) {
maxok = ok; length = ok;
} }
} }
if (maxok * nv <= dset->n && dset->n % maxok == 0) { if (length * nv <= dset->n && dset->n % length == 0) {
/* suggests that at least one var has already been stacked */ /* suggests that at least one var has already been stacked */
bign = dset->n; bign = dset->n;
maxok -= offset; length -= offset;
} else { } else {
/* no stacking done: need to expand series length */ /* no stacking done yet: need to expand series length */
bign = nv * (dset->n - offset); bign = nv * (dset->n - offset);
maxok = 0; length = 0;
} }
} }
#if PDEBUG #if PDEBUG
fprintf(stderr, "bign = %d, allocating bigx (oldn = %d)\n", bign, dset->n); fprintf(stderr, "bign = %d, allocating xstack (oldn = %d)\n", bign, dset->n) ;
#endif #endif
/* allocate stacked series */ /* allocate container for stacked data */
bigx = malloc(bign * sizeof *bigx); xstack = malloc(bign * sizeof *xstack);
if (bigx == NULL) { if (xstack == NULL) {
err = E_ALLOC; return E_ALLOC;
goto bailout;
} }
/* extend length of all series? */ /* extend length of all series? */
oldn = dset->n; oldn = dset->n;
if (bign > oldn) { if (bign > oldn) {
err = dataset_add_observations(dset, bign - oldn, OPT_NONE); err = dataset_add_observations(dset, bign - oldn, OPT_NONE);
if (err) { if (err) {
free(bigx); return err;
goto bailout;
} }
} }
/* construct stacked series */ /* construct stacked series */
for (i=0; i<nv; i++) { for (i=0; i<nv; i++) {
int j = (vnum == NULL)? i + v1 : vnum[i]; int j = list[i+1];
int t, bigt, tmax; int t, bigt, tmax;
if (maxok > 0) { if (length > 0) {
bigt = maxok * i; bigt = length * i;
tmax = offset + maxok; tmax = offset + length;
} else { } else {
bigt = oldn * i; bigt = oldn * i;
tmax = oldn; tmax = oldn;
} }
for (t=offset; t<tmax; t++) { for (t=offset; t<tmax; t++) {
bigx[bigt] = dset->Z[j][t]; xstack[bigt] = dset->Z[j][t];
if (dset->S != NULL && bigt != t) { if (dset->S != NULL && bigt != t) {
strcpy(dset->S[bigt], dset->S[t]); strcpy(dset->S[bigt], dset->S[t]);
} }
bigt++; bigt++;
} }
if (i == nv - 1) { if (i == nv - 1) {
for (t=bigt; t<bign; t++) { for (t=bigt; t<bign; t++) {
bigx[bigt++] = NADBL; xstack[bigt++] = NADBL;
} }
} }
} }
/* add stacked series to dataset */ *pstack = xstack;
if (genv == dset->v) {
/* add as new variable */
err = dataset_add_allocated_series(dset, bigx);
if (err) {
free(bigx);
goto bailout;
}
} else {
/* replace existing variable of same name */
free(dset->Z[genv]);
dset->Z[genv] = bigx;
gretl_varinfo_init(dset->varinfo[genv]);
}
/* complete the details */
if (!err) {
char *tmp = calloc(MAXLABEL, 1);
strcpy(dset->varname[genv], vname);
if (tmp != NULL) {
make_stack_label(tmp, scpy);
copy_label(&dset->varinfo[genv]->label, tmp);
free(tmp);
}
pprintf(prn, "%s %s %s (ID %d)\n",
(genv == dset->v - 1)? _("Generated") : _("Replaced"),
_("series"), vname, genv);
}
bailout:
free(vnum);
free(s);
free(scpy);
return err; return err;
} }
static int found_log_parent (const char *s, char *targ) static int found_log_parent (const char *s, char *targ)
{ {
int len = gretl_namechar_spn(s); int len = gretl_namechar_spn(s);
if (len < VNAMELEN && s[len] == ')') { if (len < VNAMELEN && s[len] == ')') {
char fmt[8]; char fmt[8];
skipping to change at line 3068 skipping to change at line 2923
if (dset->varinfo != NULL && dset->varinfo[i] != NULL) { if (dset->varinfo != NULL && dset->varinfo[i] != NULL) {
if (dset->varinfo[i]->display_name[0] != '\0') { if (dset->varinfo[i]->display_name[0] != '\0') {
ret = dset->varinfo[i]->display_name; ret = dset->varinfo[i]->display_name;
} }
} }
return ret; return ret;
} }
static int add_obs (int n, DATASET *dset, PRN *prn) static int add_obs (int n, DATASET *dset, gretlopt opt, PRN *prn)
{ {
int err = 0; int err = 0;
if (complex_subsampled()) { if (complex_subsampled()) {
pprintf(prn, _("The data set is currently sub-sampled.\n")); pprintf(prn, _("The data set is currently sub-sampled.\n"));
err = E_DATA; err = E_DATA;
} else if (n <= 0) { } else if (n <= 0) {
err = E_PARSE; err = E_PARSE;
} else if (opt & OPT_T) {
/* extending panel time */
err = panel_dataset_extend_time(dset, n);
if (!err) {
pprintf(prn, _("Panel time extended by %d observations"), n);
pputc(prn, '\n');
}
} else { } else {
err = dataset_add_observations(dset, n, OPT_A); err = dataset_add_observations(dset, n, OPT_A);
if (!err) { if (!err) {
pprintf(prn, _("Dataset extended by %d observations"), n); pprintf(prn, _("Dataset extended by %d observations"), n);
pputc(prn, '\n'); pputc(prn, '\n');
extend_function_sample_range(n); extend_function_sample_range(n);
} }
} }
return err; return err;
skipping to change at line 3433 skipping to change at line 3295
dataset sortby x1 dataset sortby x1
dataset resample 500 dataset resample 500
dataset clear dataset clear
dataset renumber orig 2 dataset renumber orig 2
dataset insobs 13 dataset insobs 13
dataset pad-daily 7 dataset pad-daily 7
*/ */
int modify_dataset (DATASET *dset, int op, const int *list, int modify_dataset (DATASET *dset, int op, const int *list,
const char *param, PRN *prn) const char *param, gretlopt opt, PRN *prn)
{ {
static int resampled; static int resampled;
int k = 0, err = 0; int k = 0, err = 0;
if (dset == NULL || dset->Z == NULL) { if (dset == NULL || dset->Z == NULL) {
return E_NODATA; return E_NODATA;
} }
#if 0 #if 0
fprintf(stderr, "modify_dataset: op=%d, param='%s'\n", op, param); fprintf(stderr, "modify_dataset: op=%d, param='%s'\n", op, param);
printlist(list, "list"); printlist(list, "list");
#endif #endif
if (op == DS_CLEAR || op == DS_RENUMBER) { if (op == DS_CLEAR || op == DS_RENUMBER) {
/* must be handled by the calling program */ /* must be handled by the calling program */
return E_NOTIMP; return E_NOTIMP;
} }
if (gretl_function_depth() > 0) { if (gretl_function_depth() > 0) {
if (op == DS_ADDOBS && !complex_subsampled() && if (op == DS_ADDOBS && !complex_subsampled() &&
dset->t2 == dset->n - 1) { dset->t2 == dset->n - 1 && !(opt & OPT_T)) {
/* experimental, 2015-07-28: allow "addobs" within a /* experimental, 2015-07-28: allow "addobs" within a
function provided the dataset is not subsampled function provided the dataset is not subsampled
*/ */
goto proceed; goto proceed;
} else { } else {
gretl_errmsg_set(_("The 'dataset' command is not available " gretl_errmsg_set(_("The 'dataset' command is not available "
"within functions")); "within functions"));
return 1; return 1;
} }
} }
skipping to change at line 3511 skipping to change at line 3373
if (dset->pd == 1) { if (dset->pd == 1) {
k = 4; k = 4;
} else if (dset->pd == 4) { } else if (dset->pd == 4) {
k = 12; k = 12;
} else { } else {
return E_PDWRONG; return E_PDWRONG;
} }
} }
if (op == DS_ADDOBS) { if (op == DS_ADDOBS) {
err = add_obs(k, dset, prn); err = add_obs(k, dset, opt, prn);
} else if (op == DS_INSOBS) { } else if (op == DS_INSOBS) {
err = insert_obs(k, dset, prn); err = insert_obs(k, dset, prn);
} else if (op == DS_COMPACT) { } else if (op == DS_COMPACT) {
err = compact_data_set_wrapper(param, dset, k); err = compact_data_set_wrapper(param, dset, k);
} else if (op == DS_EXPAND) { } else if (op == DS_EXPAND) {
int n = (param == NULL)? 0 : strlen(param); int n = (param == NULL)? 0 : strlen(param);
int interp = 0; int interp = 0;
if (n > 0 && !strncmp(param, "interpolate", n)) { if (n > 0 && !strncmp(param, "interpolate", n)) {
interp = 1; interp = 1;
skipping to change at line 4395 skipping to change at line 4257
* @i: index number of series. * @i: index number of series.
* @n_strs: location to receive the number of strings, or NULL. * @n_strs: location to receive the number of strings, or NULL.
* *
* Returns: the array of strings associated with distinct numerical * Returns: the array of strings associated with distinct numerical
* values of series @i, or NULL if there's no such array. The returned * values of series @i, or NULL if there's no such array. The returned
* array should not be modified in any way; copy the strings first if * array should not be modified in any way; copy the strings first if
* you need to modify them. * you need to modify them.
*/ */
char **series_get_string_vals (const DATASET *dset, int i, char **series_get_string_vals (const DATASET *dset, int i,
int *n_strs) int *n_strs, int subsample)
{ {
char **strs = NULL; char **strs = NULL;
int n = 0; int n = 0;
if (i > 0 && i < dset->v && dset->varinfo[i]->st != NULL) { if (i > 0 && i < dset->v && dset->varinfo[i]->st != NULL) {
strs = series_table_get_strings(dset->varinfo[i]->st, &n); strs = series_table_get_strings(dset->varinfo[i]->st, &n);
} }
if (strs != NULL && subsample && dataset_is_subsampled(dset)) {
static char **substrs = NULL;
const double *x = dset->Z[i] + dset->t1;
int T = dset->t2 - dset->t1 + 1;
gretl_matrix *valid;
int err = 0;
if (substrs != NULL) {
free(substrs);
substrs = NULL;
}
valid = gretl_matrix_values(x, T, OPT_NONE, &err);
if (err) {
strs = NULL;
n = 0;
} else {
int j, k, nv = valid->rows;
substrs = strings_array_new(nv);
for (j=0; j<nv; j++) {
k = gretl_vector_get(valid, j) - 1;
substrs[j] = strs[k];
}
strs = substrs;
n = nv;
gretl_matrix_free(valid);
}
}
if (n_strs != NULL) { if (n_strs != NULL) {
*n_strs = n; *n_strs = n;
} }
return strs; return strs;
} }
/** /**
* series_get_string_width: * series_get_string_width:
* @dset: pointer to dataset. * @dset: pointer to dataset.
skipping to change at line 4735 skipping to change at line 4626
} }
int panel_group_names_ok (const DATASET *dset, int maxlen) int panel_group_names_ok (const DATASET *dset, int maxlen)
{ {
int ok = 0; int ok = 0;
if (dataset_is_panel(dset) && dset->pangrps != NULL) { if (dataset_is_panel(dset) && dset->pangrps != NULL) {
int ns, v = current_series_index(dset, dset->pangrps); int ns, v = current_series_index(dset, dset->pangrps);
if (v > 0 && v < dset->v) { if (v > 0 && v < dset->v) {
char **S = series_get_string_vals(dset, v, &ns); char **S = series_get_string_vals(dset, v, &ns, 0);
if (S != NULL && ns >= dset->n / dset->pd) { if (S != NULL && ns >= dset->n / dset->pd) {
ok = 1; /* provisional */ ok = 1; /* provisional */
if (maxlen > 0) { if (maxlen > 0) {
int i; int i;
for (i=0; i<ns; i++) { for (i=0; i<ns; i++) {
if (strlen(S[i]) > maxlen) { if (strlen(S[i]) > maxlen) {
ok = 0; ok = 0;
break; break;
skipping to change at line 4762 skipping to change at line 4653
return ok; return ok;
} }
const char *panel_group_names_varname (const DATASET *dset) const char *panel_group_names_varname (const DATASET *dset)
{ {
if (dataset_is_panel(dset) && dset->pangrps != NULL) { if (dataset_is_panel(dset) && dset->pangrps != NULL) {
int ns, v = current_series_index(dset, dset->pangrps); int ns, v = current_series_index(dset, dset->pangrps);
if (v > 0 && v < dset->v) { if (v > 0 && v < dset->v) {
char **S = series_get_string_vals(dset, v, &ns); char **S = series_get_string_vals(dset, v, &ns, 0);
if (S != NULL) { if (S != NULL) {
int ng = dset->n / dset->pd; int ng = dset->n / dset->pd;
if (ns >= ng) { if (ns >= ng) {
return dset->pangrps; return dset->pangrps;
} }
} }
} }
} }
skipping to change at line 4798 skipping to change at line 4689
int exclude) int exclude)
{ {
int i, vfound = 0; int i, vfound = 0;
for (i=1; i<dset->v && !vfound; i++) { for (i=1; i<dset->v && !vfound; i++) {
if (i == exclude) { if (i == exclude) {
continue; continue;
} }
if (is_string_valued(dset, i)) { if (is_string_valued(dset, i)) {
int ns = 0; int ns = 0;
char **S = series_get_string_vals(dset, i, &ns); char **S = series_get_string_vals(dset, i, &ns, 0);
if (S != NULL && ns >= dset->n / dset->pd) { if (S != NULL && ns >= dset->n / dset->pd) {
const char *sbak = NULL; const char *sbak = NULL;
int t, u, ubak = -1; int t, u, ubak = -1;
int fail = 0; int fail = 0;
for (t=dset->t1; t<=dset->t2 && !fail; t++) { for (t=dset->t1; t<=dset->t2 && !fail; t++) {
const char *st = series_get_string_for_obs(dset, i, t); const char *st = series_get_string_for_obs(dset, i, t);
u = t / dset->pd; u = t / dset->pd;
skipping to change at line 4840 skipping to change at line 4731
} }
/* For plotting purposes, try to get labels for panel groups, /* For plotting purposes, try to get labels for panel groups,
subject to the constraint that they should be no longer subject to the constraint that they should be no longer
than @maxlen. If successful, this will return an array of than @maxlen. If successful, this will return an array of
at least N strings, where N is the cross-sectional at least N strings, where N is the cross-sectional
dimension of the panel. This array should be treated as dimension of the panel. This array should be treated as
read-only. read-only.
*/ */
char **get_panel_group_labels (const DATASET *dset, int maxlen) series_table *get_panel_group_table (const DATASET *dset,
int maxlen, int *pv)
{ {
char **S = NULL; series_table *st = NULL;
int altv, vpg = 0; int vpg = 0;
if (dset->pangrps != NULL) { if (dset->pangrps != NULL) {
vpg = current_series_index(dset, dset->pangrps); vpg = current_series_index(dset, dset->pangrps);
} }
/* first see if we have valid group labels set explicitly */ /* first see if we have valid group labels set explicitly */
if (vpg > 0 && panel_group_names_ok(dset, maxlen)) { if (vpg > 0 && panel_group_names_ok(dset, maxlen)) {
S = series_get_string_vals(dset, vpg, NULL); st = dset->varinfo[vpg]->st;
} }
if (S == NULL) { if (st == NULL) {
/* can we find a suitable string-valued series? */ /* can we find a suitable string-valued series? */
altv = suitable_group_names_series(dset, maxlen, vpg); int altv = suitable_group_names_series(dset, maxlen, vpg);
if (altv > 0) { if (altv > 0) {
S = series_get_string_vals(dset, altv, NULL); vpg = altv;
st = dset->varinfo[vpg]->st;
} }
} }
return S; *pv = (st != NULL)? vpg : 0;
return st;
} }
int is_dataset_series (const DATASET *dset, const double *x) int is_dataset_series (const DATASET *dset, const double *x)
{ {
int i; int i;
for (i=dset->v-1; i>=0; i--) { for (i=dset->v-1; i>=0; i--) {
if (x == dset->Z[i]) { if (x == dset->Z[i]) {
return 1; return 1;
} }
 End of changes. 45 change blocks. 
371 lines changed or deleted 267 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)