Reputation: 7
I start with some example. I have "schools" variable like "harvard and oxford", "only harvard" etc. I want to find in "schools" variable only these cases which contain only one school name ("place" variable). I have "place" variable in dataset bbb which I put in listplace ("harvard!oxford!wse), "opinion" variable which I put in listopinion ("8!8!9) and "country" variable which I put in listcountry ("usa!uk!france"). I want to make macro which find in "schools" variable only these cases which contains two school names (zm1). Then, I want to add to them appropriate item from listopinion and listplace. "Place" is school name, "opinion" is average rate and "country" is origin of this rate.
That's my first dataset: place opinion country - "harvard" 8 "usa" - "oxford" 8 "uk" - "wse" 9 "france"
That's my second dataset:
schools - harvard best - only harvard should be chosen - we dont't have any values - cake
That's what I want to have as results of my code (only two observation, not four as it is in "schools" variable):
schools opinion country - "harvard very special" 8 "usa" - "only harvard should be chosen" 8 "usa"
How can I make three %do until loops with %let statements?
data aaa;
input schools;
datalines;
"harvard and oxford"
"only harvard should be chosen"
"cheese, cake, pizza"
"we dont't have any values"
;
run;
data bbb;
input place opinion country;
datalines;
"harvard" 8 "usa"
"oxford" 8 "uk"
"wse" 9 "france"
;
run;
data ccc;
set
proc sql noprint;
select opinion
into :listopinion separated by "!"
from aaa
;
run;
quit;
proc sql noprint;
select country
into :listcountry separated by "!"
from aaa
;
run;
quit;
proc sql noprint;
select place
into :listplace separated by "!"
from aaa
;
run;
quit;
%let i_1 =1;
%let i_2 =1;
%let i_2 =1;
%do %until (%qscan(&listplace,&i_1,'!') = %str());
%do %until (%qscan(&listopinion,&i_2,'!') = %str());
%do %until (%qscan(&listcountry,&i_3,'!') = %str());
%let zm1=%scan(&listplace,&i_1,'!');
find(school,"&zm1")=1 or
%let zm2=%scan(&listopinion,&i_2,'!')
%let zm3=%scan(&lista3,&i_3,'!');
%let i_3=%eval(&i_3+1);
%end;
%let i_2=%eval(&i_2+1);
%end;
%let i_1=%eval(&i_1+1);
%end;
run;
Upvotes: 0
Views: 200
Reputation: 51566
It sounds like for your test of school you want to test if two or more of the names in the list exist in the value of school.
So if your list of schools to find looks like:
%let list=harvard|oxford|wse;
then you want to generate something like:
if sum( 0<findw(school,"harvard",,'i')
, 0<findw(school,"oxford",,'i')
, 0<findw(school,"wse",,'i')
) >= 2 then do;
...
end;
So you might use something like this:
if sum(
%let sep=;
%do i=1 %to %sysfunc(countw(&list,|));
&sep 0<findw(school,"%qscan(&list,&i,|)",,'i')
%let sep=,;
%end;
) >= 2 then do;
...
end;
I have no idea what you want to do with the other two lists. I think you want to use them to generate some SAS code where I have left ...
.
Upvotes: 0