I have character variables pt1-pt&review (the maximum ranges vary). I'm trying to find out if there is a match to main variable allpt for each of these variables by using index function for all the rows (first.id to last.id) in the dataset. If matched, the array variables check1-check&review will have value>0. Since I need to use the value of the variables pt1-pt34 for index function, I tried using macro function "call symputx..." I'm getting error messages with the codes below.
data tagged;
length id $ 8 check1-check&review 8;
do until (last.id);
set case;
by id;
array pt(&review) $;
array check(&review) $;
do i = 1 to dim(check);
call symputx ('name', pt[i]);
check[i] = index (allpt,'&name');
end;
drop i;
run;
ERROR 22-322: Syntax error, expecting one of the following: a name, _ALL_, _CHARACTER_, _CHAR_,
_NUMERIC_.
ERROR: Missing numeric suffix on a numbered variable list (check1-check).
ERROR 352-185: The length of numeric variables is 3-8.
Macro variable REVIEW resolved successfully, by the way.
Thanks for help!
This
call symputx ('name', pt[i]);
check[i] = index (PTUPC,'&name');
cannot work, for two reasons:
Why don't you just do
check[i] = index(PTUPC,strip(pt[i]));
?
If macro variable &review has leading blanks, it won't work.
Either change how you set it, or add
%let review=&review.;
to remove the blanks.
How did you create the macro variable REVIEW?
If you are using PROC SQL with the INTO clause then make sure to use the TRIMMED keyword to remove leading spaces.
proc sql noprint;
select max(review_number) into :review TRIMMED
from mydata;
quit;
You could also use %LET to remove unquoted spaces.
%let review=&review ;
Or modify your program so that leading spaces don't impact it. For example set the length of CHECK1 to CHECK8 using the ARRAY statement. Also make you your mind whether CHECK1 to CHECK8 are numeric or character. Your LENGTH statement defines them as numeric put you included a $ in your array statement. Assuming you want them as character:
data tagged;
length id $8 ;
array check(&review) $8;
Thanks for the feed back. I tried the methods suggested. I also tried using numeric version of review (as reviewn) to see if it helps.
proc sql;
select count as observation
into: review TRIMMED
from high;
quit;
%let review=&review;
%let reviewn=%eval(&review);
Good thing is using either REVIEW or REVIEWN, I no longer get any error messages. However, all my CHECK variables are 0 using the program below. I believe CHECK should be a numeric variable since it's an output from the INDEX function. I have modified the code as suggested. I am also uploading the sample data and the output I would like to see when the program runs successfully.
proc sort data=case3;by id;run;
data tagged;
length id $ 8 check1-check&review 8;
do until (last.id);
set case3;
by id;
array pt(&review) $;
array check(&review) ;
do i = 1 to dim(check);
call symputx ('name', pt[i]);
check[i] = index (PTUPC,'&name');
end;
end;
drop i;
run;
| id | pt1 | pt2 | pt3 | allpt | ck1 | ck2 | ck3 |
| a001 | ab | ab | ac | abd | 1 | 1 | 0 |
| a002 | ac | ab | dc | abd | 0 | 1 | 0 |
| a003 | ad | ab | bd | abd | 0 | 1 | 2 |
This
call symputx ('name', pt[i]);
check[i] = index (PTUPC,'&name');
cannot work, for two reasons:
Why don't you just do
check[i] = index(PTUPC,strip(pt[i]));
?
The corrected version below is working. Thank you!
data tagged;
length id $ 8 check1-check&reviewn 8;
do until (last.id);
set case3;
by id;
array pt(&reviewn) $;
array check(&reviewn) ;
do i = 1 to dim(check);
check[i] = index(PTUPC,strip(pt[i]));
end;
end;
drop i;
run;
It's finally time to hack! Remember to visit the SAS Hacker's Hub regularly for news and updates.
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.
Ready to level-up your skills? Choose your own adventure.