BookmarkSubscribeRSS Feed
☑ This topic is solved. Need further help from the community? Please sign in and ask a new question.
stataq
Quartz | Level 8

Hello,

 

I would like to find a way to subtract the punctuation out of string into multiple marco variables. 

 

For example: 

invalue="X/X(X%)"

I would like to use 'X' as delimiter to find any sign before or after 'X' and then store them into a serial of marco variables with prefix _s. So here I would like to build following macro variables:

_s1=

_s2=/

_s3=(

_s4=%)

 

If invalue="(x-x)" then the set I want will be

_s1=(

_s2=-

_s3=)

 

How can I achieve this goal? As invalue format is not the same, the punctuation position will change case by case.  

 

Thanks.

 

 

1 ACCEPTED SOLUTION

Accepted Solutions
Quentin
Super User

Paige is asking the right questions.  This is an odd thing to want to do.  Are you reading in a table shell as data?  That seems like a reasonable thing to do, and parsing the data to get the mathematical symbols is not a crazy idea, but storing the results in macro variables is probably not the best approach, depending on the big picture.

 

That said, you can do it in a DATA step, using COUNTW to find the number of works, and using SCAN to find each word.  Then CALL SYMPUTX to create a macro variable for each word. Something like:

 

data _null_ ;
  invalue="X/X(X%)" ;
  do i=1 to countw(invalue,"X","mi") ;
    call symputx(cats("_s",i),scan(invalue,i,"X","mi")) ;
  end ;
run ;

%put _user_ ;

Typically I would want to keep this data in a data set, instead of storing it in macro variable, so I might do it like:

data want ;
  invalue="X/X(X%)" ;
  length symbol $8 ;
  do i=1 to countw(invalue,"X","mi") ;
    symbol=scan(invalue,i,"X","mi") ;
    output ;
  end ;
run ;

proc print data=want ;
run ;
The Boston Area SAS Users Group is hosting free webinars!
Next up: SAS Trivia Quiz hosted by SAS on Wednesday May 21.
Register now at https://www.basug.org/events.

View solution in original post

5 REPLIES 5
PaigeMiller
Diamond | Level 26

This strikes me as a problem that is made extra difficult by using macro variables. A simplification would be to do this in a DATA step using either PRX or SCAN functions in the data step.

 

This also strikes me as a problem that could be simplified even further, if only we knew exactly why the data is arranged this way, and what you intend to do with it after you perform these string manipulations. So, @stataq, please explain the big picture: why is the data arranged this way in the first place, and what will you do with these strings once you obtain them.

--
Paige Miller
stataq
Quartz | Level 8
@PaigeMiller I was thinking to get all punctuations out and later substitute X with other values to build a new string.

PaigeMiller
Diamond | Level 26

I don't think you answered my questions. Please take a step back and provide the big picture, rather than tightly focusing on this exact piece of code that you want help with.

 

Why is the data arranged this way?

 

What will you with these character strings after you have code that extracts there character strings?

--
Paige Miller
ballardw
Super User

@stataq wrote:
@PaigeMiller I was thinking to get all punctuations out and later substitute X with other values to build a new string.


Then the order is wrong. You want what you are calling X to become macro variables, in place, and then substitute the X for macro variable references.

 

/* orginal value is
   a / b .. c
*/

%let x1=ABC;
%let x2=PDQ;
%let x3=XYZ;

%let macrostr= &x1 / &x2 .. &x3;

%put the value of macrostr is: &macrostr.;

Though still sounds moderately awkward at best without a real use case or two.

Quentin
Super User

Paige is asking the right questions.  This is an odd thing to want to do.  Are you reading in a table shell as data?  That seems like a reasonable thing to do, and parsing the data to get the mathematical symbols is not a crazy idea, but storing the results in macro variables is probably not the best approach, depending on the big picture.

 

That said, you can do it in a DATA step, using COUNTW to find the number of works, and using SCAN to find each word.  Then CALL SYMPUTX to create a macro variable for each word. Something like:

 

data _null_ ;
  invalue="X/X(X%)" ;
  do i=1 to countw(invalue,"X","mi") ;
    call symputx(cats("_s",i),scan(invalue,i,"X","mi")) ;
  end ;
run ;

%put _user_ ;

Typically I would want to keep this data in a data set, instead of storing it in macro variable, so I might do it like:

data want ;
  invalue="X/X(X%)" ;
  length symbol $8 ;
  do i=1 to countw(invalue,"X","mi") ;
    symbol=scan(invalue,i,"X","mi") ;
    output ;
  end ;
run ;

proc print data=want ;
run ;
The Boston Area SAS Users Group is hosting free webinars!
Next up: SAS Trivia Quiz hosted by SAS on Wednesday May 21.
Register now at https://www.basug.org/events.

sas-innovate-white.png

Missed SAS Innovate in Orlando?

Catch the best of SAS Innovate 2025 — anytime, anywhere. Stream powerful keynotes, real-world demos, and game-changing insights from the world’s leading data and AI minds.

 

Register now

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.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 5 replies
  • 895 views
  • 0 likes
  • 4 in conversation