Auto-suggest helps you quickly narrow down your search results by suggesting possible matches as you type.

Showing results for

Find a Community

- Home
- /
- SAS Programming
- /
- Base SAS Programming
- /
- how to delete one macro variable for another macro...

- RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page

- Mark as New
- Bookmark
- Subscribe
- RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

08-31-2012 12:42 AM

Hi all,

%let x=a1-a10;

%let y=a6;

how to delete &y (a6) from &x efficiently?

Thanks.

Accepted Solutions

Solution

08-31-2012
05:08 PM

- Mark as New
- Bookmark
- Subscribe
- RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Posted in reply to data_null__

08-31-2012 05:08 PM

Or ...

%let x=a01-a10;

%let y=a06;

**data** xx yy ;

keep vn ;

array xxx

array yyy

do i = **1** to dim(xxx) ; vn = vname(xxx*) ; output xx ; end ;*

do i = **1** to dim(yyy) ; vn = vname(yyy*) ; output yy ; end ;*

**run** ;

**proc** **sql** noprint ;

select vn into : z separated by ' '

from ( select vn from xx

except

select vn from yy ) ;

drop table xx, yy ;

**quit** ;

%put &z ;

All Replies

- Mark as New
- Bookmark
- Subscribe
- RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Posted in reply to TomiKong

08-31-2012 02:07 AM

You can't delete it from x, because it's not in x to begin with.

What you've done here is define &x as the literal string "a1-a10". I assuming you're thinking of this as a list of variables a1, a2, ..., a10, but when you define "%let x=a1-a10" SAS doesn't perform that interpretation. SAS will substitute the characters "a1-a10" in the code where "&x" appears and only then will it interpret it.

Demonstration:

%let x=a1-a3;

data test;

a1=5;

a2=6;

a3=7;

diff=&x;

sum=sum(of &x);

run;

When you run this code, the first thing SAS does is to substitute "a1-a3" where "&x" appears:

data test;

a1=5;

a2=6;

a3=7;

diff=a1-a3;

sum=sum(of a1-a3);

run;

It then interprets based on context. In the first case, it interprets "a1-a3" as a1 minus a3 (= 5-7 = -2); in the second case it interprets it as "a1, a2, a3" (= 5+6+7 = 18).

If you can give some more context on what you're looking to do, people might be able to suggest some other solution.

- Mark as New
- Bookmark
- Subscribe
- RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Posted in reply to TomiKong

08-31-2012 10:14 AM

The first answer you got was correct. But there may be ways to program around it. It all depends on what you need your application to do. Here is one possible workaround, for one particular application:

total = sum(of &x, -&y);

There are also ways to get macro language to parse the variable list into individual names. After that is done, it would be possible to remove &y from that list of individual names. But as the first reply noted, give us more context. How will you be using &x?

- Mark as New
- Bookmark
- Subscribe
- RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Posted in reply to Astounding

08-31-2012 12:15 PM

Hi Geoffrey, Astounding,

Thanks a lot for your kind reply.

X (a1-a10) are independent variable candidates for regression. Miss rate will be calculated for each of them. Then I will remove these with high miss rate from X.

I want to write one macro to do this automatically. But I still have no clue to remove variable with high miss rate from list...

Thanks again.

- Mark as New
- Bookmark
- Subscribe
- RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Posted in reply to TomiKong

08-31-2012 12:33 PM

This may be something like you are looking for. Each list X and Y are expanded and then any name in Y is removed from X and a new macro variable is created

NOTE: NEWX=a1 a2 a3 a4 a5 A7 A8 A9 A10

This will work for any type of "SAS Variable List" as long as the variables exist in a data set.

**data** test;

length a1-a5 A6-A12 **8.**;

stop;

call missing(of _all_);

**run**;

%let x=a1-a10;%let y=a6;**proc** **transpose** data=test(obs=**0**) out=x;

var &x;

**run**;

**proc** **transpose** data=test(obs=**0**) out=y;

var &y;

**run**;**proc** **sql** noprint;

select _name_ into :newX separated by ' '

from X

where _name_ ne ALL(select _name_ from Y);

**quit**;

**run**;

%put NOTE: NEWX=&newX;

Solution

08-31-2012
05:08 PM

- Mark as New
- Bookmark
- Subscribe
- RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Posted in reply to data_null__

08-31-2012 05:08 PM

Or ...

%let x=a01-a10;

%let y=a06;

**data** xx yy ;

keep vn ;

array xxx

array yyy

do i = **1** to dim(xxx) ; vn = vname(xxx*) ; output xx ; end ;*

do i = **1** to dim(yyy) ; vn = vname(yyy*) ; output yy ; end ;*

**run** ;

**proc** **sql** noprint ;

select vn into : z separated by ' '

from ( select vn from xx

except

select vn from yy ) ;

drop table xx, yy ;

**quit** ;

%put &z ;

- Mark as New
- Bookmark
- Subscribe
- RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Posted in reply to Howles

08-31-2012 06:43 PM

That's all good except it only works for enumerated variable lists.

I would like to know about my SQL SELECT since I got "NE ALL" from your book why you chose to use EXCEPT, is one better than the other?

- Mark as New
- Bookmark
- Subscribe
- RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Posted in reply to TomiKong

08-31-2012 06:53 PM

Maybe you need to show your work.

How do you calculate miss rate?

You may not have to REMOVE anything but just gen a new list of variables that have acceptable miss rate.

- Mark as New
- Bookmark
- Subscribe
- RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Posted in reply to TomiKong

09-02-2012 07:56 PM

I see you already have solutions, but you might (or might not) find that existing SAS regression options can save you the need to write your own macro.

For instance, PROC REG gives you options for stepwise selection (add variables with best explanatory power/remove variables with worst) or by using something like SELECTION=MAXR STOP=&MAXEXPVARS you can force SAS to choose the best n variables.

- Mark as New
- Bookmark
- Subscribe
- RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Posted in reply to TomiKong

08-31-2012 06:39 PM

If you only need to take out one variable name at a time, like your sample showed, you could just use the following simpler approach:

%let x=a1 a2 a3; %let y=a1;

data _null_;

new_x=tranwrd("&x","&y",'');

call symputx('x',new_x);

run;

%put &x;

If you have more than one variable names needs to be taken off the parent list, then you already have good answers above or use a little loop:

%let x=a1 a2 a3; %let y=a1 a3;

data _null_;

x="&x"; y="&y";

do i=1 by 1 to countw(y);

_y=scan(y,i);

x=tranwrd(x,trim(_y),'');

end;

call symputx('x',x);

run;

%put &x;

Haikuo

- Mark as New
- Bookmark
- Subscribe
- RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Posted in reply to TomiKong

09-01-2012 04:28 AM

Awesome. All works fine. Thank you all so much.