Since there are no errors in the log, I'm not sure what's going wrong. In the macro, I'm trying to create the variable MAJOR_CAT based on DIAG1. See blow:
%LET DATAPULL = DATATWO;
%LET OUTDATA = DATAONE;
PROC SQL;
CREATE TABLE &DATAPULL. AS SELECT
/*PULL A BUNCH OF VARIABLES WORKS FINE*/
RUN;
%MACRO MAJOR_CAT;
%IF DIAG1 =: 'F0' %THEN &MAJOR_CAT. = 'Organic, including symptomatic, mental disorders';
%IF DIAG1 =: 'F1' %THEN &MAJOR_CAT. = 'Mental and behavioural disorders due to psychoative substance use';
%IF DIAG1 =: 'F2' %THEN &MAJOR_CAT. = 'Schizophrena, schizotypal and delusional disorders';
%IF DIAG1 =: 'F3' %THEN &MAJOR_CAT. = 'Mood [affective] disorders';
%IF DIAG1 =: 'F4' %THEN &MAJOR_CAT. = 'Neurotic, stress-related and somatoform disorders';
%IF DIAG1 =: 'F5' %THEN &MAJOR_CAT. = 'Behavioural syndromes associated with physiological disturbances and physical factors';
%IF DIAG1 =: 'F6' %THEN &MAJOR_CAT. = 'Disorders of adult personality and behaviour';
%IF DIAG1 =: 'F7' %THEN &MAJOR_CAT. = 'Mental retardation';
%IF DIAG1 =: 'F8' %THEN &MAJOR_CAT. = 'Disorders of psychological development';
%IF DIAG1 =: 'F90' OR DIAG1 =: 'F91' OR DIAG1 =: 'F92' OR DIAG1 =: 'F93' OR DIAG1 =: 'F94' OR DIAG1 =: 'F95' OR DIAG1 =: 'F96'
OR DIAG1 =: 'F97' OR DIAG1 =: 'F98' %THEN &MAJOR_CAT. = 'Behavoural and emotional disorders with onset usually occurring in childhood and adolescence';
%IF DIAG1 =: 'F99' %THEN &MAJOR_CAT. = 'Unspecified mental disorder';
%MEND MAJOR_CAT;
/*HERE I CALL THE MACRO AND GET MY &DATAPULL SET SPIT OUT WITH NO MAJOR_CAT VARIABLE*/
DATA &OUTDATA.;
SET &DATAPULL.;
%MAJOR_CAT;
RUN;
Below is a non-macro program version of the macro program that works correctly:
DATA &OUTDATA.;
SET &DATAPULL.;
IF DIAG1 =: 'F0' THEN MAJOR_CAT = 'Organic, including symptomatic, mental disorders';
IF DIAG1 =: 'F1' THEN MAJOR_CAT = 'Mental and behavioural disorders due to psychoative substance use';
IF DIAG1 =: 'F2' THEN MAJOR_CAT = 'Schizophrena, schizotypal and delusional disorders';
IF DIAG1 =: 'F3' THEN MAJOR_CAT = 'Mood [affective] disorders';
IF DIAG1 =: 'F4' THEN MAJOR_CAT = 'Neurotic, stress-related and somatoform disorders';
IF DIAG1 =: 'F5' THEN MAJOR_CAT = 'Behavioural syndromes associated with physiological disturbances and physical factors';
IF DIAG1 =: 'F6' THEN MAJOR_CAT = 'Disorders of adult personality and behaviour';
IF DIAG1 =: 'F7' THEN MAJOR_CAT = 'Mental retardation';
IF DIAG1 =: 'F8' THEN MAJOR_CAT = 'Disorders of psychological development';
IF DIAG1 =: 'F90' OR DIAG1 =: 'F91' OR DIAG1 =: 'F92' OR DIAG1 =: 'F93' OR DIAG1 =: 'F94' OR DIAG1 =: 'F95' OR DIAG1 =: 'F96' OR DIAG1 =: 'F97' OR DIAG1 =: 'F98' THEN MAJOR_CAT = 'Behavoural and emotional disorders with onset usually occurring in childhood and adolescence';
IF DIAG1 =: 'F99' THEN MAJOR_CAT = 'Unspecified mental disorder';
RUN;
Definitely a valid and valuable use. It's simpler than you are thinking:
%macro mylogic;
IF DIAG1 =: 'F0' THEN MAJOR_CAT = 'Organic, including symptomatic, mental disorders';
IF DIAG1 =: 'F1' THEN MAJOR_CAT = 'Mental and behavioural disorders due to psychoative substance use';
IF DIAG1 =: 'F2' THEN MAJOR_CAT = 'Schizophrena, schizotypal and delusional disorders';
IF DIAG1 =: 'F3' THEN MAJOR_CAT = 'Mood [affective] disorders';
IF DIAG1 =: 'F4' THEN MAJOR_CAT = 'Neurotic, stress-related and somatoform disorders';
IF DIAG1 =: 'F5' THEN MAJOR_CAT = 'Behavioural syndromes associated with physiological disturbances and physical factors';
IF DIAG1 =: 'F6' THEN MAJOR_CAT = 'Disorders of adult personality and behaviour';
IF DIAG1 =: 'F7' THEN MAJOR_CAT = 'Mental retardation';
IF DIAG1 =: 'F8' THEN MAJOR_CAT = 'Disorders of psychological development';
IF DIAG1 =: 'F90' OR DIAG1 =: 'F91' OR DIAG1 =: 'F92' OR DIAG1 =: 'F93' OR DIAG1 =: 'F94' OR DIAG1 =: 'F95' OR DIAG1 =: 'F96' OR DIAG1 =: 'F97' OR DIAG1 =: 'F98' THEN MAJOR_CAT = 'Behavoural and emotional disorders with onset usually occurring in childhood and adolescence';
IF DIAG1 =: 'F99' THEN MAJOR_CAT = 'Unspecified mental disorder';
%mend mylogic;
Note that I haven't implemented any of the suggested changes to the code. You can use this statement in four places as needed:
%mylogic
Yes, but your code is IF/THEN but references a data step variable in a PROC SQL step.
You're currently mixing macro, data step and sql code in a manner that doesn't work.
I would suggest using the data step or changing the code to be CASE statements which would work in SQL. Not really sure where the macro variable major cat is created either.
Assuming you could create a macro here, how would it be useful? You already have a working program. You might need to explain a little more.
Your time would be better spent upgrading the working program. Add the word ELSE as appropriate so it will run faster. Set a length for MAJOR_CAT so its values won't get truncated. Once you have improved the non-macro code, then consider whether there would be value in converting it to a macro. But the example you have posted does not illustrate any benefits of using a macro.
there is value in converting it to a macro because I am going to use it four times or more throughout my program.
Definitely a valid and valuable use. It's simpler than you are thinking:
%macro mylogic;
IF DIAG1 =: 'F0' THEN MAJOR_CAT = 'Organic, including symptomatic, mental disorders';
IF DIAG1 =: 'F1' THEN MAJOR_CAT = 'Mental and behavioural disorders due to psychoative substance use';
IF DIAG1 =: 'F2' THEN MAJOR_CAT = 'Schizophrena, schizotypal and delusional disorders';
IF DIAG1 =: 'F3' THEN MAJOR_CAT = 'Mood [affective] disorders';
IF DIAG1 =: 'F4' THEN MAJOR_CAT = 'Neurotic, stress-related and somatoform disorders';
IF DIAG1 =: 'F5' THEN MAJOR_CAT = 'Behavioural syndromes associated with physiological disturbances and physical factors';
IF DIAG1 =: 'F6' THEN MAJOR_CAT = 'Disorders of adult personality and behaviour';
IF DIAG1 =: 'F7' THEN MAJOR_CAT = 'Mental retardation';
IF DIAG1 =: 'F8' THEN MAJOR_CAT = 'Disorders of psychological development';
IF DIAG1 =: 'F90' OR DIAG1 =: 'F91' OR DIAG1 =: 'F92' OR DIAG1 =: 'F93' OR DIAG1 =: 'F94' OR DIAG1 =: 'F95' OR DIAG1 =: 'F96' OR DIAG1 =: 'F97' OR DIAG1 =: 'F98' THEN MAJOR_CAT = 'Behavoural and emotional disorders with onset usually occurring in childhood and adolescence';
IF DIAG1 =: 'F99' THEN MAJOR_CAT = 'Unspecified mental disorder';
%mend mylogic;
Note that I haven't implemented any of the suggested changes to the code. You can use this statement in four places as needed:
%mylogic
I get the same results using MAJOR_CAT as I do &MAJOR_CAT.
Are you recommending not invoke the macro within a datastep? If I just invoke the macro as %mylogic it resolves and writes some stuff to the log but does not produce output.
You listed a program as "working". If that program works, then this one will also work
DATA &OUTDATA.;
SET &DATAPULL.;
%mylogic
run;
It generates exactly the same statements in exactly the same order.
Sorry you are right this absolutely does work I didn't notice the missing % for IF and THEN. It is not needed I guess?
That's correct. Writing a macro does not require changing all your IF THEN statements to %IF %THEN. It all depends on what the macro is intended to accomplish. The general guidelines: macros generate SAS code. The generated SAS code (not the macro language) processes your data. So the generated SAS code has to be accurate.
A format would actually be a lot cleaner IMO.
@Swann2000 wrote:
there is value in converting it to a macro because I am going to use it four times or more throughout my program.
It's finally time to hack! Remember to visit the SAS Hacker's Hub regularly for news and updates.
Learn how use the CAT functions in SAS to join values from multiple variables into a single value.
Find more tutorials on the SAS Users YouTube channel.
Ready to level-up your skills? Choose your own adventure.