BookmarkSubscribeRSS Feed
wangmh008
Calcite | Level 5

Hi guys:

I want to use tranwrd function to translate + of a macro variable to " , " , so that I can use in statement afterward.

my code is like:

%do i= 1 to 3;

%if %index(&&_col&i,+)^=0 %then %let tempcol&i=%sysfunc(tranwrd(&&_col&i,+,","));

however sas log gave me a red mark and a note : The meaning of an identifier after a quoted string might change in a future SAS release . Inserting white space  between a quoted string and the succeeding identifier is recommended. (Is there a way to solve this ?)

 

suppose I have a  &_col1= 1 + 2 ,

I want tranwrd &_col1 to  1 " , " 2 so that I can use statement :if col in ("&tempcol1") which is equal to if col in ("1","2");

 

11 REPLIES 11
Kurt_Bremser
Super User

From where do you create the original macro variable? And is the result to be used in a Subsetting IF that can be replaced by a WHERE?

wangmh008
Calcite | Level 5
Hi Kurt:
Thank you so much for the quick response. the macro variable is inherited from macro program %freqtable(trtgrp=1 2 1+2);

%let coln=%sysfunc(countw(%cmpres(&trtgrp),' '));
%do i= 1 %to &coln;
%let COLN&i=%sysfunc(compress(%scan(&trtgrp,&i,' '),,kd));
%let _COLN&i=%scan(&column,&i,' ');
%end;

data all;
set xxx;
%do i= 1 %to &coln;
%if %index(&&_coln&i,+)= 0 %then %let tempcol&i=&&_coln&i;
%if %index(&&_coln&i,+)^= 0 %then %let tempcol&i=%sysfunc(tranwrd(&&_coln&i,+,"," ));
if _colvars in ("&&tempcol&i") then do;
_colvar="&&coln&i.";
output;
end;
%end;
run;
PaigeMiller
Diamond | Level 26

It seems like a mistake to do this with macro variables. There might be many easier ways to do this. Please take a step back and explain the big picture, explain the big problem without reference to SAS code, rather than what you have provided which is a question about code.

--
Paige Miller
wangmh008
Calcite | Level 5
Thanks for the quick reply. The goal is to create a macro for frequency table. when we create the CDISC frequency table we want to count the frequency by treatment group, suppose we have treatment group 1 2 3 4 5, sometimes we also want to count for the combination group like 1+2+3+4, so when I wrote my macro I want to use + to indicate that I want to get the information of combination group %freqtable(trtgrp=1 2 3 4 5 1+2+3+4).
Is there a way to solve this problem by using functions like %quote %unquote ?
PaigeMiller
Diamond | Level 26

@wangmh008 wrote:
Thanks for the quick reply. The goal is to create a macro for frequency table. when we create the CDISC frequency table we want to count the frequency by treatment group, suppose we have treatment group 1 2 3 4 5, sometimes we also want to count for the combination group like 1+2+3+4, so when I wrote my macro I want to use + to indicate that I want to get the information of combination group %freqtable(trtgrp=1 2 3 4 5 1+2+3+4).
Is there a way to solve this problem by using functions like %quote %unquote ?

I have no idea what code inside a macro you would use to make %freqtable(trtgrp=1 2 3 4 5 1+2+3+4) work and produce meaningful results. I'm not even sure I know what the output would be for trtgrp=1 2 3 4 5 1+2+3+4. The advice I always give to people is to write code that works without macro variables and without macros for one iteration, and then it will be easier to turn that into a macro.

 

So, show us working code without macros and without macro variables for the case where trtgrp=1 2 1+2

--
Paige Miller
wangmh008
Calcite | Level 5
Hi Paige thanks for the advice, the below code could recur the error.

%let grp=1+2;

data temp;
input group;
datalines;
1
2
1
3
;
run;

data temp1;
set temp;
%if %index(&grp,+)^=0 %then %do;
%let tgrp=%sysfunc(tranwrd(&grp,+,","));
if group in ("&tgrp");
%end;
run;
PaigeMiller
Diamond | Level 26

@wangmh008 wrote:
Hi Paige thanks for the advice, the below code could recur the error.

%let grp=1+2;

data temp;
input group;
datalines;
1
2
1
3
;
run;

data temp1;
set temp;
%if %index(&grp,+)^=0 %then %do;
%let tgrp=%sysfunc(tranwrd(&grp,+,","));
if group in ("&tgrp");
%end;
run;

I asked to see code that works for this one case without macros and without macro variables. If you can't write code that works without macros and without macro variables first, then it will NEVER work with macros and with macro variables.


And since you claim you want to create frequency tables, this code does not create frequency tables.


We (or at least I) have the problem that you are showing us tiny bits of the problem, and we can't see how they all fit together to get you from some starting point to actual frequency tables.

--
Paige Miller
Tom
Super User Tom
Super User

@wangmh008 wrote:
Thanks for the quick reply. The goal is to create a macro for frequency table. when we create the CDISC frequency table we want to count the frequency by treatment group, suppose we have treatment group 1 2 3 4 5, sometimes we also want to count for the combination group like 1+2+3+4, so when I wrote my macro I want to use + to indicate that I want to get the information of combination group %freqtable(trtgrp=1 2 3 4 5 1+2+3+4).
Is there a way to solve this problem by using functions like %quote %unquote ?

So that type of macro is going to be generating SAS code.  So there is no reason to use macro code to manipulate the value of the TRTGRP macro variable. 

Write a data step that can manipulate the value of TRTGRP and convert it into what you need. 

 

If just want to convert "1 2 3 4 5 1+2+3+4" into 6 macro variables it would be trivial using actual SAS code instead of macro code.  Much easier than trying to deal with spaces and commas in macro code.

data _null_;
   string="&trtgrp";
   do index=1 to countw(string,' ');
      call symputx(cats('trt',index),tranwrd(scan(string,index,' '),'+',','));
   end;
run;

 

Most likely what you need is a multi-level format.  So you could probably generate a CNTLIN dataset that you could pass to PROC FORMAT to create the format.  Then use the format with one of the summary procedures that supports multi-level formats.

Astounding
PROC Star

There is only one place in your code where you have a character following a closing quote:

%let tempcol&i=%sysfunc(tranwrd(&&_col&i,+,","));

Try adding a space after the closing quote:

%let tempcol&i=%sysfunc(tranwrd(&&_col&i,+,"," ));

Verify that macro language ignores that blank, and gives you the result you are looking for.

wangmh008
Calcite | Level 5
still gave me the samething.

NOTE: Line generated by the macro function "SYSFUNC".
92 1","2
___
49

NOTE 49-169: The meaning of an identifier after a quoted string might change in a future SAS release. Inserting white space
between a quoted string and the succeeding identifier is recommended.
wangmh008
Calcite | Level 5

Seems like this code can work 

%if %index(&&_col&i,+)^=0 %then %let tempcol&i=%sysfunc(tranwrd(%str(&&_col&i),%str(+),%str( ", " )));

SAS Innovate 2025: Call for Content

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!

Submit your idea!

How to Concatenate Values

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.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 11 replies
  • 1028 views
  • 1 like
  • 5 in conversation