Desktop productivity for business analysts and programmers

Dealing with Parentheses in a String

Reply
Contributor
Posts: 70

Dealing with Parentheses in a String

i am facing a problem as I tryiing to make a string by using SAS Macro and SAS functions but am not able to deal with parentheses as a string. Don't know what to do.

Can someone please help me with this.

 

My Code :

 

%MACRO MA_STRING(D,N) ;

%LET MA_STRING = %NRSTR(sum%() ;

%PUT &MA_String ;

%DO I = 1 %TO &N ;

%LET MA_STRING = %SYSFUNC(CAT(&MA_String ,%STR(,) , LAG , &I , %Str(%() , &D , %Str(%)) ));

%PUT &MA_String ;

%END ;

%MEND ;

 

%MA_STRING(P,3) ;

 

 

This is the error received.

 

sum(
ERROR: Required operator not found in expression: )
sum(,LAG1.P)
ERROR: Required operator not found in expression: sum(,LAG1.P)
ERROR: Required operator not found in expression: )
sum(,LAG1.P),LAG2.P)
ERROR: Expected close parenthesis after macro function invocation not found.
LAG , 3 , ( , P , ) ))

 

Super User
Posts: 13,926

Re: Dealing with Parentheses in a String

Posted in reply to DipeshGupta

It really helps to describe what you are attempting to do. And provide examples of input and desired output.

 

And when working with macros an example of the code that worked without any macro elements.

Respected Advisor
Posts: 4,783

Re: Dealing with Parentheses in a String

Posted in reply to DipeshGupta

@DipeshGupta

As @ballardw please explain what you're trying to do and provide sample data.

On top of this: SAS Macro code generates SAS code. It appears you're trying to generate SAS code which contains the LAG() function. If so then the LAG() function must be used in a SAS Data step and you certainly can't call the macro outside of a SAS data step.

 

Super User
Posts: 6,931

Re: Dealing with Parentheses in a String

Posted in reply to DipeshGupta

Notice you have additional problems besides the parenthesis.  The code you are trying to create cannot run, since even if it worked you would end up with:

 

sum(,lag1(P), lag2(P))

 

The first item to sum isn't specified.

 

This might work or might not.  I just can't test it right now:

 

%LET MA_STRING=sum(  

     %do i=1 %to &n;

         lag&i(&d)

         %if &i < &n %then ,;

      %end;

   );

 

But even if it does work, it would be cleaner and more flexible to get rid of the %LET piece.

 

%macro MA_STRING (D, N);

 

   %local i;

   sum(  

 

   %do i=1 %to &n;  

      lag&i(&d)  

      %if &i < &n %then ,;

   %end;

    )

 

%mend MA_STRING;

 

Then within a DATA step you could call the macro to assign a value to a DATA step variable:

 

MA_STRING = %MA_STRING(P,3);

 

Notice that you are not locked in to using MA_STRING as the name of the variable being assigned a value.

SAS Super FREQ
Posts: 508

Re: Dealing with Parentheses in a String

Posted in reply to Astounding

The best place to do string processing is in a DATA step.  Then you can use regular string functions with no worries about quoting, etc.  When you are done, you can use SYMPUTX if necessary to make a macro variable.

Contributor
Posts: 70

Re: Dealing with Parentheses in a String

Posted in reply to Astounding

@Astounding This code worked successfully.

%macro MA_STRING (D, N);

 

   %local i;

   sum(  

 

   %do i=1 %to &n;  

      lag&i(&d)  

      %if &i < &n %then ,;

   %end;

    )

 

%mend MA_STRING;

 

Then within a DATA step you could call the macro to assign a value to a DATA step variable:

 

MA_STRING = %MA_STRING(P,3);

 

 

 

 

Is there a macro code to make a dataset from the string values.

 

eg my string is :

 

Bat Ball Apple

 

now I want something like this

 

Colname No.

Bat          1

Ball          2

Apple      3

 

 

What I am doing is I am creating a dataset for each word and then merging all the three datasets into one but I was wondering if there

is some other way so that I dont have to create a dataset for each word because it is taking a lot of memory.

Super User
Posts: 6,931

Re: Dealing with Parentheses in a String

Posted in reply to DipeshGupta

Of course SAS can do that.  But I'm tempted to say that you would probably be better off starting over again, and reconsidering your approach.  It sounds like you are jumping through hoops, making an easy process complicated.  If you were to post a separate question showing your original starting point, you could get some guidance on that.

 

You don't say whether your incoming string is contained in a macro variable or in a DATA step character variable.  The answer would be slightly different, but would essentially use the same tools.  The output you are showing would be a SAS data set regardless.  So assuming the original string is a macro variable:

 

data want;

length colname $ 32;

do number = 1 to countw("&string");

   colname = scan("&string", number, ' ');

   output;

end;

run;

Contributor
Posts: 70

Re: Dealing with Parentheses in a String

Posted in reply to Astounding

@Astounding Thanks for all your help, really appreciate it and I think  I got both your codes.

 

In the first code where we are making a string using macro,

 

What we are basically doing here is, when we give a statement in a macro withour referencing it to anything else then it is taken as the output of the macro so we can use it in a datastep using %jj(i,3) and it give the value which is wriiten directly in a macro whithout any reference.

 

In the second code where we are making a dataset using string,

 

What solved my problem here is the small output command you mentioned in you code because I was facing the issue of colname being overwriiten everytime the code runs and the final output was only showing the last word of the string but now with the output statement you resolved this issue also.

 

 

And now I can't help it from being a little greedy and want to ask for a help once again.

 

Suppose I have a dataset in this format.

 

ClassA      Subjects     Marks

Rahul        Maths         95

Raj            English       75

John          Accounts    97

 

And I want a dataset something like this.

 

Category     Value

ClassA         Rahul

ClassA         Raj

ClassA         John

Subjects       Maths

Subjects       English

Subjects       Accounts

Marks            95

Marks            75

Marks            97

 

Now what I am doing is I am using Proc sort with nodupkey for each column and creating a dataset for each column i.e. ClasssA Subjects Marks. eg of a data set.

 

Category     Value

ClassA         Rahul

ClassA         Raj

ClassA         John

 

Then I am merging three datasets together.

 

Is there a short method for this task also.

Super User
Posts: 6,931

Re: Dealing with Parentheses in a String

[ Edited ]
Posted in reply to DipeshGupta

Given that you know the variable names, it's straightforward.  You may need to ignore some messages about numeric to character conversion.

 

data want (keep=category value order);

set have;

length category value $ 20;

order=1;

category='ClassA';

value = ClassA;

output;

order=2;

category='Subjects';

value = Subjects;

output;

order=3;

category = 'Marks';

value = left(marks);

output;

run;

 

proc sort data=want;

by order;

run;

 

Still, I doubt the wisdom of doing this. If the data ever gets sorted differently, you can lose the relationship between the class, the subject, and the mark.

 

Contributor
Posts: 70

Re: Dealing with Parentheses in a String

Posted in reply to Astounding

@Astounding But your code will paste all the column values and I want only the unique values of the column.

Respected Advisor
Posts: 4,783

Re: Dealing with Parentheses in a String

Posted in reply to DipeshGupta

@DipeshGupta

"Then I am merging three datasets together."

The way I understand what you describe and given your sample data you would end up where you've started from after this merge.

 

The sample data you provide is already unique per row. It's also not really clear from your description if you're after unique rows or after unique values per variable. If it's after unique values per variables then I don't understand what you're trying to merge together as you'll loose the connection between the values (i.e. that it was Rahul who had a mark of 95 in maths).

Can you please explain a bit better and most importantly provide better sample data which demonstrates what you're after.

Super User
Posts: 6,931

Re: Dealing with Parentheses in a String

Posted in reply to DipeshGupta

Then you'll have to show a more specific example ... one that actually starts with duplicates and what the end result should look like.  You could easily end up with more observations for MARKS than for SUBJECTS in the final data set.  It's possible that what you are doing now is just fine.  It's also possible that maintaining the order (as my program did) is not important.  There are just too many guesses when these cases aren't illustrated and the final result should be "something like" the illustrated result.

Super User
Posts: 10,562

Re: Dealing with Parentheses in a String

Posted in reply to DipeshGupta

Heed @WarrenKuhfeld's advice.

DO NOT HANDLE DATA WITH MACRO LANGUAGE!

Use a data step and save the results with call symput/call symputx.

---------------------------------------------------------------------------------------------
Maxims of Maximally Efficient SAS Programmers
How to convert datasets to data steps
How to post code
Frequent Contributor
Posts: 118

Re: Dealing with Parentheses in a String

Posted in reply to DipeshGupta

%MACRO MA_STRING(D,N) ;

%LET MA_STRING = %NRSTR(sum%() );

%PUT &MA_String ;

%DO I = 1 %TO &N ;

%LET MA_STRING = %SYSFUNC(CAT(&MA_String ,%STR(,) , LAG , &I , %Str(%() , &D , %Str(%)) ));

%PUT &MA_String ;

%END ;

%MEND ;

 

%MA_STRING(P,3) ;

 

I think that is the problem.

Ask a Question
Discussion stats
  • 13 replies
  • 894 views
  • 2 likes
  • 7 in conversation