In my project i am taking a users input and one of the variables is key to extract. This variable is year but may be written for some datasets as say "Graduation_year" where in others it may be say "Year_of_purchase" and so on. What i need to do is take this variable out of a list to be used separately from the remainder of the list. From the example below what my desired outcome looks like is as follows: Input -> (Gender Graduation_Year Course_Name) Outputs -> Var_of_importance = Graduation_year and Remainder_vars= Gender Course_name.
The code i am using so far has come across an error as i'm trying to update a macro variable at each iteration of the second loop called size.
The code is as follows:
%macro Year_finder(var_list);
%local size;
%Put The variables are: &var_list.;
%let Keyword_loc=%Index(&var_list.,Year);
%put The location of the keyword Year begins at place number &Keyword_loc.;
%do i=1 %to %sysfunc(countw(&var_list.));
%let word_&i.=%length(%sysfunc(scan(&var_list.,&i.)));
%put The length of %sysfunc(scan(&var_list.,&i.)) is &&word_&i.;
%end;
%do i=1 %to %sysfunc(countw(&var_list.));
%if i=1 %then %do;
%if &&word_&i. LT &Keyword_loc. and &&word_(&i.+1)+1 GT &Keyword_loc. %then Word = %sysfunc(scan(&var_list.,&i.));
%let size=&&word_&i.;
%put The step number is step &i.;
%put The &i.th word has a length of &&word_&i.;
%put Initial length is &size.;
%end;
%else %do;
%eval(&size. = &size.+ &&word_&i. + 1);
%if &size. LT &Keyword_loc. and &size. + &&word_(&i.+1) + 1 GT &Keyword_loc. %then Word = %sysfunc(scan(&var_list.,(&i.+1)))
%put This step number is step &i.;
%put The length variable = &size.;
%put The word is &Word.;
%end;
%end;
%mend;
%Year_finder(Gender Graduation_Year Course_Name);
At the moment this seems like it will do what i want it to but as i cant get past this error i cannot verify it works. Any help would be greatly appreciated. Thank you.
To solve your problem, the easiest is to check if each word individually contain "year" and add them to the desired output macro variable. The following should work:
%macro Year_finder(var_list);
* Initialize output variables;
%global Var_of_importance Remainder_vars;
%let Var_of_importance = ;
%let Remainder_vars = ;
* Go through words from var_list;
%do i=1 %to %sysfunc(countw(&var_list.));
* Add word to var_of_importance if it contain "year" (not case sensitive);
%if %index(%lowcase(%scan(&var_list.,&i.)),year) %then %do;
%let Var_of_importance = &Var_of_importance %scan(&var_list.,&i.);
%end;
%else %do;
* Add word to Remainder_vars if it does not contain "year";
%let Remainder_vars = &Remainder_vars %scan(&var_list.,&i.);
%end;
%end;
%mend;
%Year_finder(Gender Graduation_Year Course_Name);
Your original code has several problems
%if i=1 %then %do;
to %if &i=1 %then %do;
%sysevalf()
to evaluate the complicated expression and you miss a %let
in your %then word =
&&word_(&i.+1)
. Instead you can write %superq(word_%eval(&i+1))
. For details see Resolving macro containing %eval in macro variable name, SAS&&word_&i.
) to the location of "year" (&Keyword_loc.
). However, you should compare the accumulated length, which you call size
%let size = %eval(&size.+ &&word_&i. + 1);