afiqjohari
afiqjohari

Reputation: 241

Unmatched quotation mark SAS

%macro name_modal();
/*Create macro variables which contain the modalities of variables*/
%do i=1 %to &num_Var;
    data _null_;
        set  &lib..Table_variable_modal_&i.;
        call symputx('num_Mod'||compress(put(&i,4.)),_N_,"G");
        call symputx('table'||compress(put(&i,4.))||'modal'||compress(put(_N_,4.)),compress(&&name_Var&i.),"G");
    run;

%end;

/*Display modalities by variable*/
%do i=1 %to &num_Var;
    %put &&name_Var&i. has &&num_Mod&i. modalities ;
    %do j=1 %to &&num_Mod&i.;
        %put %nrstr(&&tableb&i.modal&j.);
    %end;
%end;
%mend name_modal;
%name_modal();

I hope the code is self-documenting. I'll explain the problems here. Everything is working fine until I pass to the second of the program which serves to display the modalities by variables.

For example when the name of modalities being stocked in the macro variables are like
$100% BLO,
100% COLOR,
AVON & RAGOBERT,
BALLANTINE'S,
L'OREAL,
AT&T,
U-V-A
etc
I fail to use %put properly. I've tried using %bquote and %nrstr, but the problem persists. So far, the only solution I can see is to modify the name of the modalities but since the names come from a client, I don't have the possibility to make amendment on the data.

Thank you

Upvotes: 4

Views: 529

Answers (2)

Robbie Liu
Robbie Liu

Reputation: 1511

After trying a few times, I find %superq could solve this problem. Handling special characters in macro is troublesome. This page provides some useful tips on macro quoting.

I simplified your code here to the following

UPDATE: make it double-loop case.

data test;
 input name ~ &  $15.;
 datalines;
 100% BLO
 100% COLOR
 AVON & RAGOBERT
 BALLANTINE'S
 L'OREAL
 AT&T
 U-V-A
 ;
run;

%macro name_modal();
/*Create macro variables which contain the modalities of variables*/
%do i=1 %to 4;
    data _null_;
     set  test;
     call symputx('num_Mod1',_N_,"G");
     call symputx('tableb'||compress(put(&i,4.))||'modal'||compress(put(_N_,4.)),name,"G");
    run;
%end;

   %do i=1 %to 4;
    %do j=1 %to 7;
        %put %superq(tableb&i.modal&j);
    %end;
   %end;
%mend name_modal;
%name_modal();

The result will display correctly.

Note that it is %superq(tableb&i.modal&j) not %superq(&&tableb&i.modal&j) as superq accepts macro variable name without extra ampersand.

Upvotes: 2

Jay Corbett
Jay Corbett

Reputation: 28411

It is hard to answer the question for all your sample data because I can't recreate your code (missing global macros).

[UPDATE] It is more difficult to get macros to resolve which include characters that need to be masked. Post some code that can be executed, and more help can be provided.

Here is a good link for macro quoting.

This has a really good diagram detailing which macro masking functions to use for different situations.

%Str will work even if a % or & are included in the string, as long as they are followed by a space. %NRSTR if either could be interpreted as a macro variable or macro call. You can precede a single quote (') or single double quote (") with a percent sign (%), or use BQUOTE or NRBQUOTE (if your character string includes & or %).

Here is a start [UPDATE]:

%Macro Test(var=);
 %Put &var;
%Mend test;

%Test(Var=%str($100% BLO)) ;

%Test(Var=%str(100% COLOR)) ;
%Test(Var=%nrstr(100 %COLOR)) ;

%Test(Var=%str(AVON & RAGOBERT)) ;
%Test(Var=%nrstr(AVON &RAGOBERT)) ;

%Test(Var=%str(BALLANTINE%'S)) ;
%Test(Var=%bquote(BALLANTINE'S)) ;

%Test(Var=%str(L%'OREAL)) ;
%Test(Var=%bquote(L'OREAL)) ;

%Test(Var=%nrstr(AT&T)) ;
%Test(Var=%str(U-V-A)) ;

Upvotes: 1

Related Questions