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

Hi everyone,

 

I am working with an excel document attached below: This excel file is a categorical file that contains categorical variables which are not completely related. i.e. if you take a row and go across it from left to right, each new variable value is not related to the other. Data is:

 

Screen Shot 2018-07-24 at 19.56.50.png

 

My objective is to store each of these categorical fields in a separate macro variable list. The codes i have written are:

 

proc import datafile="/home/frupaul0/Carpenter/Demo1.xlsx" dbms=xlsx out=Categories;
run;

 proc sql noprint;
select
quote(trim(House)),
Portfolio,
quote(trim(City))
into :List_house separated by '',
:List_portfolio separated by '',
:List_city separated by ''
from Categories;
quit;

%put &List_city;

 

When the %put Statement is run, i notice some quoted spaces as shown blow:

Screen Shot 2018-07-24 at 19.42.14.png

 

How can I get rid of those quoted blanks at the end please?

1 ACCEPTED SOLUTION

Accepted Solutions
Tom
Super User Tom
Super User

Use a CASE statement to avoid adding quotes around missing values. 

Make a space delimited list instead of comma delimited list to avoid the extra commas.  SAS doesn't need commas between the values in the list.

proc sql noprint ;
 select case when missing(city) then city else quote(trim(city)) end
      , case when missing(house) then house else quote(trim(house)) end
  into :city_list separated by ' '
     , :house_list separated by ' '
  from test
 ;
quit;

 If you want to you can remove the trailing unquoted (and un-macro quoted) spaces with a simple %LET . But is it probably not needed.

%let city_list=&city_list;

 

 

View solution in original post

15 REPLIES 15
frupaul
Quartz | Level 8

Sorry I posted without asking my question. How can I get rid of those quoted blanks? Is there any function that can help me achieve this?

novinosrin
Tourmaline | Level 20

you mean trailing blanks

 

use trim

 

quote(trim(House))

frupaul
Quartz | Level 8

Not really. I have just edited question because i realised i omitted the trim function. The problem is with the quoted blanks (as shown in the log) contained in the macro variable. Please refer to post

novinosrin
Tourmaline | Level 20

missing values???

 

should add a condition to ignore missing values perhaps, like

 

and not missing(var);

frupaul
Quartz | Level 8

That would work if i were only creating one variable list. In this case i am creating three variable list. Using that condition will drop out values for the other categorical variables

novinosrin
Tourmaline | Level 20

Can you please post a sample data with a few records of what you have and your requirement. So people can work with and offer you a solution

frupaul
Quartz | Level 8

Just adding in sample data as requested (excel file supporting this is included in original post):

Screen Shot 2018-07-24 at 19.56.50.png

Reeza
Super User

I strongly suspect you're building something better done with formats. 

Please consider looking into  it first before building these macro variable lists.

 

Either way, add a filter to the where clause to avoid selecting missing. 

 

where not missing(house);

or 

where not missing(city);
Tom
Super User Tom
Super User

Use a CASE statement to avoid adding quotes around missing values. 

Make a space delimited list instead of comma delimited list to avoid the extra commas.  SAS doesn't need commas between the values in the list.

proc sql noprint ;
 select case when missing(city) then city else quote(trim(city)) end
      , case when missing(house) then house else quote(trim(house)) end
  into :city_list separated by ' '
     , :house_list separated by ' '
  from test
 ;
quit;

 If you want to you can remove the trailing unquoted (and un-macro quoted) spaces with a simple %LET . But is it probably not needed.

%let city_list=&city_list;

 

 

Astounding
PROC Star

Just use 3 SELECT statements instead of 1.  Each can have its own WHERE clause, such as:

 

select quote(trim(House)) into :List_house separated by ' '  where house > ' '  from categories;

frupaul
Quartz | Level 8

I had that as an option. However the data i have posted on here only contains 3 Fields. The original data I am working with contains 35 Fields.

 

I was hoping there will be a direct way to accomplish that with one proc sql

Astounding
PROC Star

You still only need one PROC SQL.  Multiple SELECT statements are allowed.

 

It's probably easiest and clearest to write a small macro:

 

%macro onelist (varname);

 

select quote(trim(&varname)) into :List_&varname separated by ' '  where &varname > ' '  from categories;

 

%mend one_list;

 

Then you can go with:

 

proc sql;

%onelist (house)

%onelist (portfolio)

%onelist (city)

etc.

quit;

 

Less typing, definitely less error-prone.

 

frupaul
Quartz | Level 8

This sounds like a sensible approach. However, all these codes i have written are part of a macro I am building. Can i create a macro within a macro? That would be the solution if that is possible

Astounding
PROC Star

There's no need to create a macro within a macro.  (That would be bad practice.) 

 

Just create two macros.  One macro is allowed to call another macro.  The only requirement is that both macros have to exist when you actually execute the code.

SAS Innovate 2025: Save the Date

 SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!

Save the date!

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.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 15 replies
  • 2344 views
  • 2 likes
  • 6 in conversation