if I define 2 lists of variables as :
%let varlist1 = v1 v2 v3
%let varlist2 = v3
How could I generate a new variable list consisting of v1 and v2 by subtracting varlist2 from varlist1? The following command does not seem to give what I want.
%let varlist3 = tranwrd(&varlist1., &varlist2., '').
Thanks.
Hi
Yout code works, but you must call tranwrd inside a %sysfunc macro function to use it outside a data step, and also omit the quotes around the empty value, as they are considered part of the value in macro language.
%let varlist3 = %sysfunc(tranwrd(&varlist1., &varlist2., %str()));
Hi
Yout code works, but you must call tranwrd inside a %sysfunc macro function to use it outside a data step, and also omit the quotes around the empty value, as they are considered part of the value in macro language.
%let varlist3 = %sysfunc(tranwrd(&varlist1., &varlist2., %str()));
It comes here.. You need a macro to remove the values in varlist2 one at a time.
%let varlist1 = V1 V2 V3 V4 V5;
%let varlist2 = V3 V1 ;
%macro m;
%global varlist3;
%let varlist3 = &varlist1;
%do i = 1 %to %sysfunc(countw(&varlist2));
%let varlist3 = %sysfunc(tranwrd(&varlist3., %scan(&varlist2.,&i,%str( )), %str()));
%end;
%let varlist3 = %sysfunc(compbl(&varlist3));
%mend;
%m;
%put &varlist3;
%let varlist1 = V1 V2 V3 V4 V5; %let varlist2 = V3 V1; %let pid=\b%sysfunc(prxchange(s/\s+/\b|\b/,-1,&varlist2))\b; %let want=%sysfunc(prxchange(s/&pid//i,-1,&varlist1)); %put &want;
- Note that it only works with 1 value in varlist2, as the tranword function takes the list as a single string to search for. It is more complicated with several values. Do you need that?
You probably need to consider the possibility that the name of the variable you want to remove is a substring of another variable in your list. You could add some spaces to the first two arguments to make it match words. Also watch out for case of the variable names.
10 %let varlist=V1v3 V2 V3 ;
11 %let var=v3 ;
12 %let want=%sysfunc(tranwrd(%str( %upcase(&varlist) ),%str( %upcase(&var) ),%str( )));
13 %put WANT=|&want|;
WANT=|V1V3 V2|
Now if you want to the second parameter to also be a list you will need a more complicated solution. You could do it with %DO looip or possible using regular expressions.
As you all suggested, this solution doesn't work if varlist 2 contains multiple stirngs separated by spaces. In fact, none of the components would be removed from varlist1. Can you please give a solution to that scenario?
If you need to do it totally in macro code then you probably want a loop. For example you could make a new macro "function".
%macro subset(list1,list2);
%local i word result;
%do i=1 %to %sysfunc(countw(&list1));
%let word=%scan(&list1,&i);
%if not %index(%str( %upcase(&list2) ),%str( %upcase(&word) )) %then
%let result=&result &word
;
%end;
&result.
%mend subset;
So then you can use it this way.
38 %let want=%subset(V1 v2 v3 v4 v5 V3v2,V3 v2);
39 %put WANT=|&want|;
WANT=|V1 v4 v5 V3v2|
Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 25. Read more here about why you should contribute and what is in it for you!
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.