BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
SasStatistics
Pyrite | Level 9

I am trying to decide whether a car type has Hybrid cars or not and will write that out in a footnote when creating a report. 

%let make=Honda;

data &make(keep=Make Model Type MSRP HybridFlag);
    set sashelp.cars end=lastrow; * is used in the SET statement to create a temporary variable named LastRow. LastRow is initialized to 0 and will be set to 1 when the last row is read from the input table. It serves as an end-of-file indicator.;
    where upcase(Make)="%upcase(&make)";
    retain HybridFlag;
    if Type="Hybrid" then HybridFlag=1;
    if lastrow then do;  * *********************** These are empty do loops; 
        if HybridFlag=1 then do;
            %let foot=&make Offers Hybrid Cars;
        end;
        else do;
            %let foot=&make Does Not Have a Hybrid Car;
        end;
    end;
run;

title "&make Cars";
footnote "&foot";

proc print data=&make noobs;
	var Model Type MSRP HybridFlag;
run;
title;footnote;

So the answer in the report is that Honda does not have a Hybrid car despite that it obviously has. 

In the second row of the code I tried: 

 

set sashelp.cars(obs=2) end=lastrow;

to only include Hybrid cars (I did this since I got out of ideas and simply needed to "play" with the code). This produced the wrong footnote again. 

I have no clue why this error occurs. 


The output table from the proc print statement: 

 

 

   
ModelTypeHybridFlag
Civic Hybrid 4dr manual (gas/electric)Hybrid1
Insight 2dr (gas/electric)Hybrid1
Pilot LXSUV1
CR-V LXSUV1
Element LXSUV1
Civic DX 2drSedan1
Civic HX 2drSedan1
Civic LX 4drSedan1
Accord LX 2drSedan1
Accord EX 2drSedan1
Civic EX 4drSedan1
Civic Si 2dr hatchSedan1
Accord LX V6 4drSedan1
Accord EX V6 2drSedan1
Odyssey LXSedan1
Odyssey EXSedan1
S2000 convertible 2drSports1

Honda Does Not Have a Hybrid Car



My question:
1. Why does the error occur (The footnote is that Honda does not have a Hybrid car despite that it obviously has) ?

2. I know that the problem can be handled by the function: symputx but my understanding of it is limited since I don't understand question 1 from the first place. 

Thanks. 

 

1 ACCEPTED SOLUTION

Accepted Solutions
s_lassen
Meteorite | Level 14

%LET statements are not part of the data step code, and will not be executed conditionally in an IF statement.

 

Instead, use CALL SYMPUT or CALL SYMPUTX:

 

%let make=Honda;

data &make(keep=Make Model Type MSRP HybridFlag);
    set sashelp.cars end=lastrow; * is used in the SET statement to create a temporary variable named LastRow. LastRow is initialized to 0 and will be set to 1 when the last row is read from the input table. It serves as an end-of-file indicator.;
    where upcase(Make)="%upcase(&make)";
    retain HybridFlag;
    if Type="Hybrid" then HybridFlag=1;
    if lastrow then do;  * *********************** These are NOT empty do loops; 
        if HybridFlag=1 then do;
            call symputx('foot',"&make Offers Hybrid Cars");
        end;
        else do;
            call symputx('foot',"&make Does Not Have a Hybrid Car");
        end;
    end;
run;

title "&make Cars";
footnote "&foot";

proc print data=&make noobs;
	var Model Type MSRP HybridFlag;
run;
title;footnote;

With you original construct, both %LET statements were executed (before execution of the data step), and the last one was the one that had effect.

 

If you do not want the flag variable, you can simplify your code like this:

%let make=Honda;

%let foot=&make Does Not Have a Hybrid Car;
data &make(keep=Make Model Type MSRP);
    set sashelp.cars;
    where upcase(Make)="%upcase(&make)";
    if Type="Hybrid" then 
      call symputx('foot',"&make Offers Hybrid Cars");
run;

title "&make Cars";
footnote "&foot";

proc print data=&make noobs;
	var Model Type MSRP;
run;
title;footnote;

 

 

 

View solution in original post

2 REPLIES 2
PaigeMiller
Diamond | Level 26

The key to writing macros that work is to write SAS code that works for one instance (in this case, Honda) that does not have macros and does not have macro variables. Once you get that to work properly, then you should be able to turn it into a macro relatively easily. If you don't have working code without macros, then it is unlikely that your macro will work. In this case, you have obviously not done this step, because your code does not produce the desired results. So you need to do this step.

 

To debug existing macros, you should use the command 

 

options mprint;

as the first line of your program, then re-run the program and look at the LOG. If looking at the log doesn't help you debug, then show us the log, by copying it as text and pasting it into the window that appears when you click on the </> icon. DO NOT POST THE LOG WITHOUT CLICKING ON THE </> ICON.

--
Paige Miller
s_lassen
Meteorite | Level 14

%LET statements are not part of the data step code, and will not be executed conditionally in an IF statement.

 

Instead, use CALL SYMPUT or CALL SYMPUTX:

 

%let make=Honda;

data &make(keep=Make Model Type MSRP HybridFlag);
    set sashelp.cars end=lastrow; * is used in the SET statement to create a temporary variable named LastRow. LastRow is initialized to 0 and will be set to 1 when the last row is read from the input table. It serves as an end-of-file indicator.;
    where upcase(Make)="%upcase(&make)";
    retain HybridFlag;
    if Type="Hybrid" then HybridFlag=1;
    if lastrow then do;  * *********************** These are NOT empty do loops; 
        if HybridFlag=1 then do;
            call symputx('foot',"&make Offers Hybrid Cars");
        end;
        else do;
            call symputx('foot',"&make Does Not Have a Hybrid Car");
        end;
    end;
run;

title "&make Cars";
footnote "&foot";

proc print data=&make noobs;
	var Model Type MSRP HybridFlag;
run;
title;footnote;

With you original construct, both %LET statements were executed (before execution of the data step), and the last one was the one that had effect.

 

If you do not want the flag variable, you can simplify your code like this:

%let make=Honda;

%let foot=&make Does Not Have a Hybrid Car;
data &make(keep=Make Model Type MSRP);
    set sashelp.cars;
    where upcase(Make)="%upcase(&make)";
    if Type="Hybrid" then 
      call symputx('foot',"&make Offers Hybrid Cars");
run;

title "&make Cars";
footnote "&foot";

proc print data=&make noobs;
	var Model Type MSRP;
run;
title;footnote;

 

 

 

sas-innovate-2024.png

Available on demand!

Missed SAS Innovate Las Vegas? Watch all the action for free! View the keynotes, general sessions and 22 breakouts on demand.

 

Register now!

How to Concatenate Values

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.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 2 replies
  • 395 views
  • 2 likes
  • 3 in conversation