1

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!!

5
  • 1
    %DATATYP is a SAS-provided autocall macro (and maybe %ISNUM also). Are you sure you've assigned the autocall library? Commented Mar 9, 2016 at 20:23
  • 1
    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. Commented Mar 9, 2016 at 20:48
  • 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. Commented Mar 9, 2016 at 22:57
  • 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]. Commented Mar 10, 2016 at 5:34
  • Could you post the fixed macro? I've just begun coding in sas and this could be quite useful. Thanks! Commented Apr 4, 2017 at 8:36

1 Answer 1

2

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;
Sign up to request clarification or add additional context in comments.

1 Comment

Use th VTYPE() function in a data step to find the type of an existing variable. Using %DATATYPE() on the value of a macro will not work. A character variable can have a value of '0' which would look like a number to %DATATYPE().

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.