1
votes

I am trying to summarize my variables using proc sql and proc freq procedures in a macro.

Here is the code:

%macro des_freq(input= ,vars= );
  %let n=%sysfunc(countw(&vars));
  %let binary=NO;
  %do i = 1 %to &n;
    %let values = %scan(&vars, &i);
      %if %datatyp(&values)=NUMERIC %then %do;
        proc summary data = &input;
          output out=x min(&values)=minx max(&values)=maxx;
        run;
        data _null_;
          set x;
          if minx = 0 and maxx = 1 then call symputx('binary','YES');
        run;
        %if &binary = YES %then %do;
          proc sql;
            select segment_final,
                  (sum(case when &values = 1 then 1 else 0 end)/ count(*)) * 100      as &values._percent
            from &input
            group by segment_final;
          quit;
        %end;
        %else %do;
          proc freq data =&input;
            tables segment_final*&values/nofreq nopercent nocol;
          run;
        %end;
      %end;

     %else %do;
        proc freq data =&input;
           tables segment_final*&values/nofreq nopercent nocol;
        run;
     %end;
  %end;
%mend;

My variables can be numeric or character. If it's numeric, it can 2 more distinct values.

I want % of 1's in a binary variable by segments(hence proc sql) and % of all distinct variables for each segment(hence proc freq).

My first if statement is checking whether the variable if numeric or not and then if its numeric, next few steps is checking if its binary or not. If its binary then execute the proc sql else execute proc freq.

If the variable is character then just execute the proc freq.

I am not able to figure out how to check if my variable is numeric or not. I tried %SYSFUNC(Vartype), %isnum and %DATATYP. None of them seem to work. Please help!!

1
%DATATYP is a SAS-provided autocall macro (and maybe %ISNUM also). Are you sure you've assigned the autocall library?Chris J
The %DATATYPE of a variable name is always going to be character since a variable name must start with a letter. Remember macro code operates on character strings.Tom
I would recommend using the sashelp.vcolumn to separate numeric and character variables first and then move your processing forward to check for binary versus ordinal/nominal. This sounds like an automated data mining solution - I'm fairly certain I've seen sample code for this in Lexjansen.com. You may want to look into some of the pre written macros for ideas.Reeza
Another possibility is to use output from a proc contents, which will tell you the type of all variables in the input dataset. You can then either use this info in a join or with a select :into [macro delimited variables].Dominic Comtois
Could you post the fixed macro? I've just begun coding in sas and this could be quite useful. Thanks!emilBeBri

1 Answers

2
votes

First you can look into sashelp.vcolumn table to check variables types:

data want(keep=libname  memname name type);
    set sashelp.vcolumn( where= (libname='SASHELP' and memname='CLASS'));
run;

If you don't want to use vcolumn table, you can use vtype() data step function as @Tom suggest:

data _NULL_;
    set  &input (obs=1);
    call symput('binary',ifc(vtype(&values)='N','YES','NO' ));
run;