Golob
Golob

Reputation: 179

Using VTYPE on dataset with 0 observations

When using VTYPE on a dataset with 0 observations I do not get needed information.

Here is MWE:

Create simple set with 1 variable and 1 observation.

data fullset;
myvar=1;
run;

Create another set with same 1 variable and 0 observations.

data emptyset;
set fullset;
stop;
run;

Make a macro that opens set, checks vtype and prints it to log.

%macro mwe(inset);  
%local TYPE;

data _NULL_;
set &inset.;
CALL SYMPUT("TYPE", VTYPE(myvar));
put TYPE;
stop;
run;

%put &=TYPE.;
%mend mwe;

When run on set with observations everything works fine:

%mwe(fullset);
TYPE=N

But when run with an empty set the TYPE does not get assigned

%mwe(emptyset);
TYPE=

I guess the reason is that no code lines are processed since the set has no observations. Is there any workaround for that?

NOTE:Using proc contents and parsing the result table is certainly an overkill for such a simple task

Upvotes: 0

Views: 451

Answers (2)

user667489
user667489

Reputation: 9569

An alternative approach is to use the vartype function instead, which does not require a set statement and unlike the vtype function can be used in pure macro code outside a data step (without resorting to dosubl or the like).

What all this means in practice is that you can use vartype to make a function-style macro version of vtype, like so:

%macro vtype(ds,var);
  %local dsid varnum rc vartype;
  %let dsid = %sysfunc(open(&ds));
  %let varnum = %sysfunc(varnum(&dsid,&var));
  %let vartype = %sysfunc(vartype(&dsid,&varnum));
  %let rc = %sysfunc(close(&dsid));
  &vartype
%mend vtype;

/*Example*/
%put %vtype(emptyset,myvar);

/*Output*/
N

Upvotes: 2

Joe
Joe

Reputation: 63424

Your problem is not vtype(), but how the data step works with an empty dataset.

When the set statement attempts to pull a row and fails, the data step immediately terminates. This can be useful - for example, when you don't want it to do things after the last row in the dataset is past. But in this case, it is less useful. Your datastep terminates instantly upon the set statement, meaning your call symput never occurs.

However, you can take advantage of a different thing: the fact that SAS will happily create all of the metadata even before set, during compilation.

%macro mwe(inset);  
%local TYPE;

data _NULL_;
CALL SYMPUT("TYPE", VTYPE(myvar));
set &inset.;
stop;
run;

%put &=TYPE.;
%mend mwe;

Notice I moved the call symput before the set. Yes, vtype() works fine even before set - the variables are still defined in the PDV even before anything happens in the data step.

(I also took out the spurious put statement that never will do anything as no TYPE variable is ever created in either version.)

Upvotes: 2

Related Questions